Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Cfg.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Cfg.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Cfg.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,2280 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Cfg.c
+// 設定情報操作モジュール
+
+#define	CFG_C
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+// 設定ファイルのバックアップの作成
+void BackupCfg(FOLDER *f, char *original)
+{
+	wchar_t *original_w = CopyStrToUni(original);
+
+	BackupCfgW(f, original_w);
+
+	Free(original_w);
+}
+void BackupCfgW(FOLDER *f, wchar_t *original)
+{
+	wchar_t dirname[MAX_PATH];
+	wchar_t filename[MAX_PATH];
+	wchar_t fullpath[MAX_PATH];
+	SYSTEMTIME st;
+	// 引数チェック
+	if (f == NULL || filename == NULL)
+	{
+		return;
+	}
+
+	// ディレクトリ名を決定
+	UniFormat(dirname, sizeof(dirname), L"@backup.%s", original[0] == L'@' ? original + 1 : original);
+
+	// ファイル名を決定
+	LocalTime(&st);
+	UniFormat(filename, sizeof(filename), L"%04u%02u%02u%02u_%s",
+		st.wYear, st.wMonth, st.wDay, st.wHour, original[0] == L'@' ? original + 1 : original);
+
+	// このファイル名が存在するかどうかチェックする
+	if (IsFileExistsW(filename))
+	{
+		return;
+	}
+
+	// ディレクトリ作成
+	MakeDirW(dirname);
+
+	// ファイル保存
+	UniFormat(fullpath, sizeof(fullpath), L"%s/%s", dirname, filename);
+	CfgSaveW(f, fullpath);
+}
+
+// 設定ファイル R/W を閉じる
+void FreeCfgRw(CFG_RW *rw)
+{
+	// 引数チェック
+	if (rw == NULL)
+	{
+		return;
+	}
+
+	if (rw->Io != NULL)
+	{
+		FileClose(rw->Io);
+	}
+
+	DeleteLock(rw->lock);
+	Free(rw->FileNameW);
+	Free(rw->FileName);
+	Free(rw);
+}
+
+// 設定ファイルの書き込み
+UINT SaveCfgRw(CFG_RW *rw, FOLDER *f)
+{
+	UINT ret = 0;
+	// 引数チェック
+	if (rw == NULL || f == NULL)
+	{
+		return 0;
+	}
+
+	Lock(rw->lock);
+	{
+		if (rw->Io != NULL)
+		{
+			FileClose(rw->Io);
+			rw->Io = NULL;
+		}
+
+		if (CfgSaveExW2(rw, f, rw->FileNameW, &ret))
+		{
+			if (rw->DontBackup == false)
+			{
+				BackupCfgW(f, rw->FileNameW);
+			}
+		}
+		else
+		{
+			ret = 0;
+		}
+
+		rw->Io = FileOpenW(rw->FileNameW, false);
+	}
+	Unlock(rw->lock);
+
+	return ret;
+}
+
+// 設定ファイル R/W の作成
+CFG_RW *NewCfgRw(FOLDER **root, char *cfg_name)
+{
+	return NewCfgRwEx(root, cfg_name, false);
+}
+CFG_RW *NewCfgRwW(FOLDER **root, wchar_t *cfg_name)
+{
+	return NewCfgRwExW(root, cfg_name, false);
+}
+CFG_RW *NewCfgRwEx(FOLDER **root, char *cfg_name, bool dont_backup)
+{
+	wchar_t *cfg_name_w = CopyStrToUni(cfg_name);
+	CFG_RW *ret = NewCfgRwExW(root, cfg_name_w, dont_backup);
+
+	Free(cfg_name_w);
+
+	return ret;
+}
+CFG_RW *NewCfgRwExW(FOLDER **root, wchar_t *cfg_name, bool dont_backup)
+{
+	CFG_RW *rw;
+	FOLDER *f;
+	// 引数チェック
+	if (cfg_name == NULL || root == NULL)
+	{
+		return NULL;
+	}
+
+	f = CfgReadW(cfg_name);
+	if (f == NULL)
+	{
+		rw = ZeroMalloc(sizeof(CFG_RW));
+		rw->lock = NewLock();
+		rw->FileNameW = CopyUniStr(cfg_name);
+		rw->FileName = CopyUniToStr(cfg_name);
+		rw->Io = FileCreateW(cfg_name);
+		*root = NULL;
+		rw->DontBackup = dont_backup;
+
+		return rw;
+	}
+
+	rw = ZeroMalloc(sizeof(CFG_RW));
+	rw->FileNameW = CopyUniStr(cfg_name);
+	rw->FileName = CopyUniToStr(cfg_name);
+	rw->Io = FileOpenW(cfg_name, false);
+	rw->lock = NewLock();
+
+	*root = f;
+
+	rw->DontBackup = dont_backup;
+
+	return rw;
+}
+
+// ファイルをコピーする
+bool FileCopy(char *src, char *dst)
+{
+	BUF *b;
+	bool ret = false;
+	// 引数チェック
+	if (src == NULL || dst == NULL)
+	{
+		return false;
+	}
+
+	b = ReadDump(src);
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	SeekBuf(b, 0, 0);
+
+	ret = DumpBuf(b, dst);
+
+	FreeBuf(b);
+
+	return ret;
+}
+bool FileCopyW(wchar_t *src, wchar_t *dst)
+{
+	BUF *b;
+	bool ret = false;
+	// 引数チェック
+	if (src == NULL || dst == NULL)
+	{
+		return false;
+	}
+
+	b = ReadDumpW(src);
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	SeekBuf(b, 0, 0);
+
+	ret = DumpBufW(b, dst);
+
+	FreeBuf(b);
+
+	return ret;
+}
+
+// ファイルへ設定を保存する
+void CfgSave(FOLDER *f, char *name)
+{
+	CfgSaveEx(NULL, f, name);
+}
+void CfgSaveW(FOLDER *f, wchar_t *name)
+{
+	CfgSaveExW(NULL, f, name);
+}
+bool CfgSaveEx(CFG_RW *rw, FOLDER *f, char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = CfgSaveExW(rw, f, name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool CfgSaveExW(CFG_RW *rw, FOLDER *f, wchar_t *name)
+{
+	return CfgSaveExW2(rw, f, name, NULL);
+}
+bool CfgSaveExW2(CFG_RW *rw, FOLDER *f, wchar_t *name, UINT *written_size)
+{
+	wchar_t tmp[MAX_SIZE];
+	bool text = true;
+	UCHAR hash[SHA1_SIZE];
+	BUF *b;
+	IO *o;
+	bool ret = true;
+	UINT dummy_int = 0;
+	// 引数チェック
+	if (name == NULL || f == NULL)
+	{
+		return false;
+	}
+	if (written_size == NULL)
+	{
+		written_size = &dummy_int;
+	}
+
+	// 同じディレクトリにある SAVE_BINARY_FILE_NAME_SWITCH ファイルがあるかどうか確認
+	if (IsFileExistsW(SAVE_BINARY_FILE_NAME_SWITCH))
+	{
+		text = false;
+	}
+
+	// バッファに変換
+	b = CfgFolderToBuf(f, text);
+	if (b == NULL)
+	{
+		return false;
+	}
+	// 内容をハッシュする
+	Hash(hash, b->Buf, b->Size, true);
+
+	// 最後に書き込んだ内容と書き込む内容を比較する
+	if (rw != NULL)
+	{
+		if (Cmp(hash, rw->LashHash, SHA1_SIZE) == 0)
+		{
+			// 内容が変更されていない
+			ret = false;
+		}
+		else
+		{
+			Copy(rw->LashHash, hash, SHA1_SIZE);
+		}
+	}
+
+	if (ret || OS_IS_UNIX(GetOsInfo()->OsType))
+	{
+		// 一時的なファイル名の生成
+		UniFormat(tmp, sizeof(tmp), L"%s.log", name);
+		// 現在存在するファイルを一時ファイルにコピー
+		FileCopyW(name, tmp);
+
+		// 新しいファイルを保存
+		o = FileCreateW(name);
+		if (o != NULL)
+		{
+			if (FileWrite(o, b->Buf, b->Size) == false)
+			{
+				// ファイル保存失敗
+				FileClose(o);
+				FileDeleteW(name);
+				FileRenameW(tmp, name);
+
+				if (rw != NULL)
+				{
+					Zero(rw->LashHash, sizeof(rw->LashHash));
+				}
+			}
+			else
+			{
+				// ファイル保存成功
+				FileClose(o);
+				// 一時ファイルの削除
+				FileDeleteW(tmp);
+			}
+		}
+		else
+		{
+			// ファイル保存失敗
+			FileRenameW(tmp, name);
+
+			if (rw != NULL)
+			{
+				Zero(rw->LashHash, sizeof(rw->LashHash));
+			}
+		}
+	}
+
+	*written_size = b->Size;
+
+	// メモリ解放
+	FreeBuf(b);
+
+	return ret;
+}
+
+// ファイルから設定を読み込む
+FOLDER *CfgRead(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	FOLDER *ret = CfgReadW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+FOLDER *CfgReadW(wchar_t *name)
+{
+	wchar_t tmp[MAX_SIZE];
+	wchar_t newfile[MAX_SIZE];
+	BUF *b;
+	IO *o;
+	UINT size;
+	void *buf;
+	FOLDER *f;
+	bool delete_new = false;
+	bool binary_file = false;
+	bool invalid_file = false;
+	UCHAR header[8];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	// 新しいファイル名の生成
+	UniFormat(newfile, sizeof(newfile), L"%s.new", name);
+	// 一時的なファイル名の生成
+	UniFormat(tmp, sizeof(tmp), L"%s.log", name);
+
+	// 新しいファイルが存在していれば読み込む
+	o = FileOpenW(newfile, false);
+	if (o == NULL)
+	{
+		// 一時的なファイルを読む
+		o = FileOpenW(tmp, false);
+	}
+	else
+	{
+		delete_new = true;
+	}
+	if (o == NULL)
+	{
+		// 一時的なファイルが無い場合は本来のファイルを読む
+		o = FileOpenW(name, false);
+	}
+	else
+	{
+		// 一時的なファイルのサイズが 0 の場合も本来のファイルを読み込む
+		if (FileSize(o) == 0)
+		{
+			invalid_file = true;
+		}
+
+		if (invalid_file)
+		{
+			FileClose(o);
+			o = FileOpenW(name, false);
+		}
+	}
+	if (o == NULL)
+	{
+		// 読み込みに失敗した
+		return NULL;
+	}
+
+	// バッファに読み込む
+	size = FileSize(o);
+	buf = Malloc(size);
+	FileRead(o, buf, size);
+	b = NewBuf();
+	WriteBuf(b, buf, size);
+	SeekBuf(b, 0, 0);
+
+	// ファイルを閉じる
+	FileClose(o);
+
+	if (delete_new)
+	{
+		// 新しいファイルを削除する
+		FileDeleteW(newfile);
+	}
+
+	// バッファの先頭 8 文字が "SEVPN_DB" の場合はバイナリファイル
+	ReadBuf(b, header, sizeof(header));
+	if (Cmp(header, TAG_BINARY, 8) == 0)
+	{
+		UCHAR hash1[SHA1_SIZE], hash2[SHA1_SIZE];
+		binary_file = true;
+
+		// ハッシュチェック
+		ReadBuf(b, hash1, sizeof(hash1));
+
+		Hash(hash2, ((UCHAR *)b->Buf) + 8 + SHA1_SIZE, b->Size - 8 - SHA1_SIZE, true);
+
+		if (Cmp(hash1, hash2, SHA1_SIZE) != 0)
+		{
+			// 破損ファイル
+			invalid_file = true;
+			FreeBuf(b);
+			return NULL;
+		}
+	}
+
+	SeekBuf(b, 0, 0);
+
+	if (binary_file)
+	{
+		SeekBuf(b, 8 + SHA1_SIZE, 0);
+	}
+
+	// バッファからフォルダに変換
+	if (binary_file == false)
+	{
+		// テキストモード
+		f = CfgBufTextToFolder(b);
+	}
+	else
+	{
+		// バイナリモード
+		f = CfgBufBinToFolder(b);
+	}
+
+	// メモリ解放
+	Free(buf);
+	FreeBuf(b);
+
+	FileDeleteW(newfile);
+
+	return f;
+}
+
+// Cfg のテスト
+void CfgTest2(FOLDER *f, UINT n)
+{
+}
+
+void CfgTest()
+{
+#if	0
+	FOLDER *root;
+	BUF *b;
+	Debug("\nCFG Test Begin\n");
+
+	root = CfgCreateFolder(NULL, TAG_ROOT);
+	CfgTest2(root, 5);
+
+	b = CfgFolderToBufText(root);
+	//Print("%s\n", b->Buf);
+	SeekBuf(b, 0, 0);
+
+	CfgDeleteFolder(root);
+
+	DumpBuf(b, "test1.config");
+
+	root = CfgBufTextToFolder(b);
+
+	FreeBuf(b);
+
+	b = CfgFolderToBufText(root);
+//	Print("%s\n", b->Buf);
+	DumpBuf(b, "test2.config");
+	FreeBuf(b);
+
+	CfgSave(root, "test.txt");
+
+	CfgDeleteFolder(root);
+
+	Debug("\nCFG Test End\n");
+#endif
+}
+
+// 1 行読み込む
+char *CfgReadNextLine(BUF *b)
+{
+	char *tmp;
+	char *buf;
+	UINT len;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	// 次の改行までの文字数を調査
+	tmp = (char *)b->Buf + b->Current;
+	if ((b->Size - b->Current) == 0)
+	{
+		// 最後まで読んだ
+		return NULL;
+	}
+	len = 0;
+	while (true)
+	{
+		if (tmp[len] == 13 || tmp[len] == 10)
+		{
+			if (tmp[len] == 13)
+			{
+				if (len < (b->Size - b->Current))
+				{
+					len++;
+				}
+			}
+			break;
+		}
+		len++;
+		if (len >= (b->Size - b->Current))
+		{
+			break;
+		}
+	}
+
+	// len だけ読み込む
+	buf = ZeroMalloc(len + 1);
+	ReadBuf(b, buf, len);
+	SeekBuf(b, 1, 1);
+
+	if (StrLen(buf) >= 1)
+	{
+		if (buf[StrLen(buf) - 1] == 13)
+		{
+			buf[StrLen(buf) - 1] = 0;
+		}
+	}
+
+	return buf;
+}
+
+// テキストストリームを読み込む
+bool CfgReadNextTextBUF(BUF *b, FOLDER *current)
+{
+	char *buf;
+	TOKEN_LIST *token;
+	char *name;
+	char *string;
+	char *data;
+	bool ret;
+	FOLDER *f;
+
+	// 引数チェック
+	if (b == NULL || current == NULL)
+	{
+		return false;
+	}
+
+	ret = true;
+
+	// 1 行読み込む
+	buf = CfgReadNextLine(b);
+	if (buf == NULL)
+	{
+		return false;
+	}
+
+	// この行を解析
+	token = ParseToken(buf, "\t ");
+	if (token == NULL)
+	{
+		Free(buf);
+		return false;
+	}
+
+	if (token->NumTokens >= 1)
+	{
+		if (!StrCmpi(token->Token[0], TAG_DECLARE))
+		{
+			if (token->NumTokens >= 2)
+			{
+				// declare
+				name = CfgUnescape(token->Token[1]);
+
+				// フォルダの作成
+				f = CfgCreateFolder(current, name);
+
+				// 次のフォルダを読み込む
+				while (true)
+				{
+					if (CfgReadNextTextBUF(b, f) == false)
+					{
+						break;
+					}
+				}
+
+				Free(name);
+			}
+		}
+		if (!StrCmpi(token->Token[0], "}"))
+		{
+			// end
+			ret = false;
+		}
+		if (token->NumTokens >= 3)
+		{
+			name = CfgUnescape(token->Token[1]);
+			data = token->Token[2];
+
+			if (!StrCmpi(token->Token[0], TAG_STRING))
+			{
+				// string
+				wchar_t *uni;
+				UINT uni_size;
+				string = CfgUnescape(data);
+				uni_size = CalcUtf8ToUni(string, StrLen(string));
+				if (uni_size != 0)
+				{
+					uni = Malloc(uni_size);
+					Utf8ToUni(uni, uni_size, string, StrLen(string));
+					CfgAddUniStr(current, name, uni);
+					Free(uni);
+				}
+				Free(string);
+			}
+			if (!StrCmpi(token->Token[0], TAG_INT))
+			{
+				// uint
+				CfgAddInt(current, name, ToInt(data));
+			}
+			if (!StrCmpi(token->Token[0], TAG_INT64))
+			{
+				// uint64
+				CfgAddInt64(current, name, ToInt64(data));
+			}
+			if (!StrCmpi(token->Token[0], TAG_BOOL))
+			{
+				// bool
+				bool b = false;
+				if (!StrCmpi(data, TAG_TRUE))
+				{
+					b = true;
+				}
+				else if (ToInt(data) != 0)
+				{
+					b = true;
+				}
+				CfgAddBool(current, name, b);
+			}
+			if (!StrCmpi(token->Token[0], TAG_BYTE))
+			{
+				// byte
+				char *unescaped_b64 = CfgUnescape(data);
+				void *tmp = Malloc(StrLen(unescaped_b64) * 4 + 64);
+				int size = B64_Decode(tmp, unescaped_b64, StrLen(unescaped_b64));
+				CfgAddByte(current, name, tmp, size);
+				Free(tmp);
+				Free(unescaped_b64);
+			}
+
+			Free(name);
+		}
+	}
+
+	// トークンの解放
+	FreeToken(token);
+
+	Free(buf);
+
+	return ret;
+}
+
+// ストリームテキストをフォルダに変換
+FOLDER *CfgBufTextToFolder(BUF *b)
+{
+	FOLDER *f, *c;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	// root フォルダから再帰的に読み込む
+	c = CfgCreateFolder(NULL, "tmp");
+
+	while (true)
+	{
+		// テキストストリームを読み込む
+		if (CfgReadNextTextBUF(b, c) == false)
+		{
+			break;
+		}
+	}
+
+	// root フォルダの取得
+	f = CfgGetFolder(c, TAG_ROOT);
+	if (f == NULL)
+	{
+		// root フォルダが見つからない
+		CfgDeleteFolder(c);
+		return NULL;
+	}
+
+	// tmp フォルダから root への参照を削除
+	Delete(c->Folders, f);
+	f->Parent = NULL;
+
+	// tmp フォルダを削除
+	CfgDeleteFolder(c);
+
+	// root フォルダを返す
+	return f;
+}
+
+// 次のフォルダを読み込む
+void CfgReadNextFolderBin(BUF *b, FOLDER *parent)
+{
+	char name[MAX_SIZE];
+	FOLDER *f;
+	UINT n, i;
+	UINT size;
+	UCHAR *buf;
+	wchar_t *string;
+	// 引数チェック
+	if (b == NULL || parent == NULL)
+	{
+		return;
+	}
+
+	// フォルダ名
+	ReadBufStr(b, name, sizeof(name));
+	f = CfgCreateFolder(parent, name);
+
+	// サブフォルダ数
+	n = ReadBufInt(b);
+	for (i = 0;i < n;i++)
+	{
+		// サブフォルダ
+		CfgReadNextFolderBin(b, f);
+	}
+
+	// アイテム数
+	n = ReadBufInt(b);
+	for (i = 0;i < n;i++)
+	{
+		UINT type;
+
+		// 名前
+		ReadBufStr(b, name, sizeof(name));
+		// 種類
+		type = ReadBufInt(b);
+
+		switch (type)
+		{
+		case ITEM_TYPE_INT:
+			// int
+			CfgAddInt(f, name, ReadBufInt(b));
+			break;
+
+		case ITEM_TYPE_INT64:
+			// int64
+			CfgAddInt64(f, name, ReadBufInt64(b));
+			break;
+
+		case ITEM_TYPE_BYTE:
+			// data
+			size = ReadBufInt(b);
+			buf = ZeroMalloc(size);
+			ReadBuf(b, buf, size);
+			CfgAddByte(f, name, buf, size);
+			Free(buf);
+			break;
+
+		case ITEM_TYPE_STRING:
+			// string
+			size = ReadBufInt(b);
+			buf = ZeroMalloc(size + 1);
+			ReadBuf(b, buf, size);
+			string = ZeroMalloc(CalcUtf8ToUni(buf, StrLen(buf)) + 4);
+			Utf8ToUni(string, 0, buf, StrLen(buf));
+			CfgAddUniStr(f, name, string);
+			Free(string);
+			Free(buf);
+			break;
+
+		case ITEM_TYPE_BOOL:
+			// bool
+			CfgAddBool(f, name, ReadBufInt(b) == 0 ? false : true);
+			break;
+		}
+	}
+}
+
+// バイナリをフォルダに変換
+FOLDER *CfgBufBinToFolder(BUF *b)
+{
+	FOLDER *f, *c;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	// 一時フォルダを作成
+	c = CfgCreateFolder(NULL, "tmp");
+
+	// バイナリを読み込む
+	CfgReadNextFolderBin(b, c);
+
+	// root の取得
+	f = CfgGetFolder(c, TAG_ROOT);
+	if (f == NULL)
+	{
+		// 見つからない
+		CfgDeleteFolder(c);
+		return NULL;
+	}
+
+	Delete(c->Folders, f);
+	f->Parent = NULL;
+
+	CfgDeleteFolder(c);
+
+	return f;
+}
+
+// フォルダをバイナリに変換
+BUF *CfgFolderToBufBin(FOLDER *f)
+{
+	BUF *b;
+	UCHAR hash[SHA1_SIZE];
+	// 引数チェック
+	if (f == NULL)
+	{
+		return NULL;
+	}
+
+	b = NewBuf();
+
+	// ヘッダ
+	WriteBuf(b, TAG_BINARY, 8);
+
+	// ハッシュ領域
+	Zero(hash, sizeof(hash));
+	WriteBuf(b, hash, sizeof(hash));
+
+	// ルートフォルダを出力 (再帰)
+	CfgOutputFolderBin(b, f);
+
+	// ハッシュ
+	Hash(((UCHAR *)b->Buf) + 8, ((UCHAR *)b->Buf) + 8 + SHA1_SIZE, b->Size - 8 - SHA1_SIZE, true);
+
+	return b;
+}
+
+// フォルダをストリームテキストに変換
+BUF *CfgFolderToBufText(FOLDER *f)
+{
+	return CfgFolderToBufTextEx(f, false);
+}
+BUF *CfgFolderToBufTextEx(FOLDER *f, bool no_banner)
+{
+	BUF *b;
+	// 引数チェック
+	if (f == NULL)
+	{
+		return NULL;
+	}
+
+	// ストリーム作成
+	b = NewBuf();
+
+	// 著作権情報
+	if (no_banner == false)
+	{
+		WriteBuf(b, TAG_CPYRIGHT, StrLen(TAG_CPYRIGHT));
+	}
+
+	// ルートフォルダを出力 (再帰)
+	CfgOutputFolderText(b, f, 0);
+
+	return b;
+}
+
+// フォルダ内容を出力 (フォルダを列挙)
+bool CfgEnumFolderProc(FOLDER *f, void *param)
+{
+	CFG_ENUM_PARAM *p;
+	// 引数チェック
+	if (f == NULL || param == NULL)
+	{
+		return false;
+	}
+
+	p = (CFG_ENUM_PARAM *)param;
+	// フォルダ内容を出力 (再帰)
+	CfgOutputFolderText(p->b, f, p->depth);
+
+	return true;
+}
+
+// アイテム内容を出力 (列挙)
+bool CfgEnumItemProc(ITEM *t, void *param)
+{
+	CFG_ENUM_PARAM *p;
+	// 引数チェック
+	if (t == NULL || param == NULL)
+	{
+		return false;
+	}
+
+	p = (CFG_ENUM_PARAM *)param;
+	CfgAddItemText(p->b, t, p->depth);
+
+	return true;
+}
+
+// フォルダ内容を出力 (再帰、バイナリ)
+void CfgOutputFolderBin(BUF *b, FOLDER *f)
+{
+	UINT i;
+	// 引数チェック
+	if (b == NULL || f == NULL)
+	{
+		return;
+	}
+
+	// フォルダ名
+	WriteBufStr(b, f->Name);
+
+	// サブフォルダ個数
+	WriteBufInt(b, LIST_NUM(f->Folders));
+
+	// サブフォルダ
+	for (i = 0;i < LIST_NUM(f->Folders);i++)
+	{
+		FOLDER *sub = LIST_DATA(f->Folders, i);
+		CfgOutputFolderBin(b, sub);
+
+		if ((i % 100) == 99)
+		{
+			YieldCpu();
+		}
+	}
+
+	// アイテム個数
+	WriteBufInt(b, LIST_NUM(f->Items));
+
+	// アイテム
+	for (i = 0;i < LIST_NUM(f->Items);i++)
+	{
+		char *utf8;
+		UINT utf8_size;
+		ITEM *t = LIST_DATA(f->Items, i);
+
+		// アイテム名
+		WriteBufStr(b, t->Name);
+
+		// 型
+		WriteBufInt(b, t->Type);
+
+		switch (t->Type)
+		{
+		case ITEM_TYPE_INT:
+			// 整数
+			WriteBufInt(b, *((UINT *)t->Buf));
+			break;
+
+		case ITEM_TYPE_INT64:
+			// 64bit 整数
+			WriteBufInt64(b, *((UINT64 *)t->Buf));
+			break;
+
+		case ITEM_TYPE_BYTE:
+			// データサイズ
+			WriteBufInt(b, t->size);
+			// データ
+			WriteBuf(b, t->Buf, t->size);
+			break;
+
+		case ITEM_TYPE_STRING:
+			// 文字列
+			utf8_size = CalcUniToUtf8((wchar_t *)t->Buf) + 1;
+			utf8 = ZeroMalloc(utf8_size);
+			UniToUtf8(utf8, utf8_size, (wchar_t *)t->Buf);
+			WriteBufInt(b, StrLen(utf8));
+			WriteBuf(b, utf8, StrLen(utf8));
+			Free(utf8);
+			break;
+
+		case ITEM_TYPE_BOOL:
+			// ブール型
+			if (*((bool *)t->Buf) == false)
+			{
+				WriteBufInt(b, 0);
+			}
+			else
+			{
+				WriteBufInt(b, 1);
+			}
+			break;
+		}
+	}
+}
+
+// フォルダ内容を出力 (再帰、テキスト)
+void CfgOutputFolderText(BUF *b, FOLDER *f, UINT depth)
+{
+	CFG_ENUM_PARAM p;
+	// 引数チェック
+	if (b == NULL || f == NULL)
+	{
+		return;
+	}
+
+	// フォルダの開始を出力
+	CfgAddDeclare(b, f->Name, depth);
+	depth++;
+
+	Zero(&p, sizeof(CFG_ENUM_PARAM));
+	p.depth = depth;
+	p.b = b;
+	p.f = f;
+
+	// アイテム一覧を列挙
+	CfgEnumItem(f, CfgEnumItemProc, &p);
+
+	if (LIST_NUM(f->Folders) != 0 && LIST_NUM(f->Items) != 0)
+	{
+		WriteBuf(b, "\r\n", 2);
+	}
+
+	// フォルダ一覧を列挙
+	CfgEnumFolder(f, CfgEnumFolderProc, &p);
+	// フォルダの終了を出力
+	depth--;
+	CfgAddEnd(b, depth);
+
+	//WriteBuf(b, "\r\n", 2);
+}
+
+// アイテム内容を出力
+void CfgAddItemText(BUF *b, ITEM *t, UINT depth)
+{
+	char *data;
+	char *sub = NULL;
+	UINT len;
+	UINT size;
+	char *utf8;
+	UINT utf8_size;
+	wchar_t *string;
+	// 引数チェック
+	if (b == NULL || t == NULL)
+	{
+		return;
+	}
+
+	// データ種類別に処理をする
+	data = NULL;
+	switch (t->Type)
+	{
+	case ITEM_TYPE_INT:
+		data = Malloc(32);
+		ToStr(data, *((UINT *)t->Buf));
+		break;
+
+	case ITEM_TYPE_INT64:
+		data = Malloc(64);
+		ToStr64(data, *((UINT64 *)t->Buf));
+		break;
+
+	case ITEM_TYPE_BYTE:
+		data = ZeroMalloc(t->size * 4 + 32);
+		len = B64_Encode(data, t->Buf, t->size);
+		data[len] = 0;
+		break;
+
+	case ITEM_TYPE_STRING:
+		string = t->Buf;
+		utf8_size = CalcUniToUtf8(string);
+		utf8_size++;
+		utf8 = ZeroMalloc(utf8_size);
+		utf8[0] = 0;
+		UniToUtf8(utf8, utf8_size, string);
+		size = utf8_size;
+		data = utf8;
+		break;
+
+	case ITEM_TYPE_BOOL:
+		size = 32;
+		data = Malloc(size);
+		if (*((bool *)t->Buf) == false)
+		{
+			StrCpy(data, size, TAG_FALSE);
+		}
+		else
+		{
+			StrCpy(data, size, TAG_TRUE);
+		}
+		break;
+	}
+	if (data == NULL)
+	{
+		return;
+	}
+
+	// データ行を出力
+	CfgAddData(b, t->Type, t->Name, data, sub, depth);
+
+	// メモリ解放
+	Free(data);
+	if (sub != NULL)
+	{
+		Free(sub);
+	}
+}
+
+// データ行を出力
+void CfgAddData(BUF *b, UINT type, char *name, char *data, char *sub, UINT depth)
+{
+	char *tmp;
+	char *name2;
+	char *data2;
+	char *sub2 = NULL;
+	UINT tmp_size;
+	// 引数チェック
+	if (b == NULL || type == 0 || name == NULL || data == NULL)
+	{
+		return;
+	}
+
+	name2 = CfgEscape(name);
+	data2 = CfgEscape(data);
+	if (sub != NULL)
+	{
+		sub2 = CfgEscape(sub);
+	}
+
+	tmp_size = StrLen(name2) + StrLen(data2) + 2 + 64 + 1;
+	tmp = Malloc(tmp_size);
+
+	if (sub2 != NULL)
+	{
+		StrCpy(tmp, tmp_size, CfgTypeToStr(type));
+		StrCat(tmp, tmp_size, " ");
+		StrCat(tmp, tmp_size, name2);
+		StrCat(tmp, tmp_size, " ");
+		StrCat(tmp, tmp_size, data2);
+		StrCat(tmp, tmp_size, " ");
+		StrCat(tmp, tmp_size, sub2);
+	}
+	else
+	{
+		StrCpy(tmp, tmp_size, CfgTypeToStr(type));
+		StrCat(tmp, tmp_size, " ");
+		StrCat(tmp, tmp_size, name2);
+		StrCat(tmp, tmp_size, " ");
+		StrCat(tmp, tmp_size, data2);
+	}
+
+	Free(name2);
+	Free(data2);
+	if (sub2 != NULL)
+	{
+		Free(sub2);
+	}
+	CfgAddLine(b, tmp, depth);
+	Free(tmp);
+}
+
+// データ種類文字列を整数値に変換
+UINT CfgStrToType(char *str)
+{
+	if (!StrCmpi(str, TAG_INT)) return ITEM_TYPE_INT;
+	if (!StrCmpi(str, TAG_INT64)) return ITEM_TYPE_INT64;
+	if (!StrCmpi(str, TAG_BYTE)) return ITEM_TYPE_BYTE;
+	if (!StrCmpi(str, TAG_STRING)) return ITEM_TYPE_STRING;
+	if (!StrCmpi(str, TAG_BOOL)) return ITEM_TYPE_BOOL;
+	return 0;
+}
+
+// データの種類を文字列に変換
+char *CfgTypeToStr(UINT type)
+{
+	switch (type)
+	{
+	case ITEM_TYPE_INT:
+		return TAG_INT;
+	case ITEM_TYPE_INT64:
+		return TAG_INT64;
+	case ITEM_TYPE_BYTE:
+		return TAG_BYTE;
+	case ITEM_TYPE_STRING:
+		return TAG_STRING;
+	case ITEM_TYPE_BOOL:
+		return TAG_BOOL;
+	}
+	return NULL;
+}
+
+// End 行を出力
+void CfgAddEnd(BUF *b, UINT depth)
+{
+	// 引数チェック
+	if (b == NULL)
+	{
+		return;
+	}
+
+	CfgAddLine(b, "}", depth);
+//	CfgAddLine(b, TAG_END, depth);
+}
+
+// Declare 行を出力
+void CfgAddDeclare(BUF *b, char *name, UINT depth)
+{
+	char *tmp;
+	char *name2;
+	UINT tmp_size;
+	// 引数チェック
+	if (b == NULL || name == NULL)
+	{
+		return;
+	}
+
+	name2 = CfgEscape(name);
+
+	tmp_size = StrLen(name2) + 2 + StrLen(TAG_DECLARE);
+	tmp = Malloc(tmp_size);
+
+	Format(tmp, 0, "%s %s", TAG_DECLARE, name2);
+	CfgAddLine(b, tmp, depth);
+	CfgAddLine(b, "{", depth);
+	Free(tmp);
+	Free(name2);
+}
+
+// 1 行を出力
+void CfgAddLine(BUF *b, char *str, UINT depth)
+{
+	UINT i;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < depth;i++)
+	{
+		WriteBuf(b, "\t", 1);
+	}
+	WriteBuf(b, str, StrLen(str));
+	WriteBuf(b, "\r\n", 2);
+}
+
+// フォルダをストリームに変換
+BUF *CfgFolderToBuf(FOLDER *f, bool textmode)
+{
+	return CfgFolderToBufEx(f, textmode, false);
+}
+BUF *CfgFolderToBufEx(FOLDER *f, bool textmode, bool no_banner)
+{
+	// 引数チェック
+	if (f == NULL)
+	{
+		return NULL;
+	}
+
+	if (textmode)
+	{
+		return CfgFolderToBufTextEx(f, no_banner);
+	}
+	else
+	{
+		return CfgFolderToBufBin(f);;
+	}
+}
+
+// 文字列のエスケープ復元
+char *CfgUnescape(char *str)
+{
+	char *tmp;
+	char *ret;
+	char tmp2[16];
+	UINT len, wp, i;
+	UINT code;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	len = StrLen(str);
+	tmp = ZeroMalloc(len + 1);
+	wp = 0;
+	if (len == 1 && str[0] == '$')
+	{
+		// 空文字
+		tmp[0] = 0;
+	}
+	else
+	{
+		for (i = 0;i < len;i++)
+		{
+			if (str[i] != '$')
+			{
+				tmp[wp++] = str[i];
+			}
+			else
+			{
+				tmp2[0] = '0';
+				tmp2[1] = 'x';
+				tmp2[2] = str[i + 1];
+				tmp2[3] = str[i + 2];
+				i += 2;
+				tmp2[4] = 0;
+				code = ToInt(tmp2);
+				tmp[wp++] = (char)code;
+			}
+		}
+	}
+	ret = Malloc(StrLen(tmp) + 1);
+	StrCpy(ret, StrLen(tmp) + 1, tmp);
+	Free(tmp);
+	return ret;
+}
+
+// 文字列のエスケープ
+char *CfgEscape(char *str)
+{
+	char *tmp;
+	char *ret;
+	char tmp2[16];
+	UINT len;
+	UINT wp, i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	len = StrLen(str);
+	tmp = ZeroMalloc(len * 3 + 2);
+	if (len == 0)
+	{
+		// 空文字
+		StrCpy(tmp, (len * 3 + 2), "$");
+	}
+	else
+	{
+		// 空文字以外
+		wp = 0;
+		for (i = 0;i < len;i++)
+		{
+			if (CfgCheckCharForName(str[i]))
+			{
+				tmp[wp++] = str[i];
+			}
+			else
+			{
+				tmp[wp++] = '$';
+				Format(tmp2, sizeof(tmp2), "%02X", (UINT)str[i]);
+				tmp[wp++] = tmp2[0];
+				tmp[wp++] = tmp2[1];
+			}
+		}
+	}
+	ret = Malloc(StrLen(tmp) + 1);
+	StrCpy(ret, 0, tmp);
+	Free(tmp);
+	return ret;
+}
+
+// 名前に使用することができる文字かどうかチェック
+bool CfgCheckCharForName(char c)
+{
+	if (c >= 0 && c <= 31)
+	{
+		return false;
+	}
+	if (c == ' ' || c == '\t')
+	{
+		return false;
+	}
+	if (c == '$')
+	{
+		return false;
+	}
+	return true;
+}
+
+// string 型の値の取得
+bool CfgGetStr(FOLDER *f, char *name, char *str, UINT size)
+{
+	wchar_t *tmp;
+	UINT tmp_size;
+	// 引数チェック
+	if (f == NULL || name == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	str[0] = 0;
+
+	// unicode 文字列を一時的に取得する
+	tmp_size = size * 4 + 10; // 一応これくらいとっておく
+	tmp = Malloc(tmp_size);
+	if (CfgGetUniStr(f, name, tmp, tmp_size) == false)
+	{
+		// 失敗
+		Free(tmp);
+		return false;
+	}
+
+	// ANSI 文字列にコピー
+	UniToStr(str, size, tmp);
+	Free(tmp);
+
+	return true;
+}
+
+// unicode_string 型の値の取得
+bool CfgGetUniStr(FOLDER *f, char *name, wchar_t *str, UINT size)
+{
+	ITEM *t;
+	// 引数チェック
+	if (f == NULL || name == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	str[0] = 0;
+
+	t = CfgFindItem(f, name);
+	if (t == NULL)
+	{
+		return false;
+	}
+	if (t->Type != ITEM_TYPE_STRING)
+	{
+		return false;
+	}
+	UniStrCpy(str, size, t->Buf);
+	return true;
+}
+
+// フォルダの存在を確認
+bool CfgIsFolder(FOLDER *f, char *name)
+{
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return false;
+	}
+
+	return (CfgGetFolder(f, name) == NULL) ? false : true;
+}
+
+// アイテムの存在を確認
+bool CfgIsItem(FOLDER *f, char *name)
+{
+	ITEM *t;
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return false;
+	}
+
+	t = CfgFindItem(f, name);
+	if (t == NULL)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// byte[] 型を BUF で取得
+BUF *CfgGetBuf(FOLDER *f, char *name)
+{
+	ITEM *t;
+	BUF *b;
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return NULL;
+	}
+
+	t = CfgFindItem(f, name);
+	if (t == NULL)
+	{
+		return NULL;
+	}
+
+	b = NewBuf();
+	WriteBuf(b, t->Buf, t->size);
+	SeekBuf(b, 0, 0);
+
+	return b;
+}
+
+// byte[] 型の値の取得
+UINT CfgGetByte(FOLDER *f, char *name, void *buf, UINT size)
+{
+	ITEM *t;
+	// 引数チェック
+	if (f == NULL || name == NULL || buf == NULL)
+	{
+		return 0;
+	}
+
+	t = CfgFindItem(f, name);
+	if (t == NULL)
+	{
+		return 0;
+	}
+	if (t->Type != ITEM_TYPE_BYTE)
+	{
+		return 0;
+	}
+	if (t->size <= size)
+	{
+		Copy(buf, t->Buf, t->size);
+		return t->size;
+	}
+	else
+	{
+		Copy(buf, t->Buf, size);
+		return t->size;
+	}
+}
+
+// int64 型の値の取得
+UINT64 CfgGetInt64(FOLDER *f, char *name)
+{
+	ITEM *t;
+	UINT64 *ret;
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return 0;
+	}
+
+	t = CfgFindItem(f, name);
+	if (t == NULL)
+	{
+		return 0;
+	}
+	if (t->Type != ITEM_TYPE_INT64)
+	{
+		return 0;
+	}
+	if (t->size != sizeof(UINT64))
+	{
+		return 0;
+	}
+
+	ret = (UINT64 *)t->Buf;
+	return *ret;
+}
+
+// bool 型の値の取得
+bool CfgGetBool(FOLDER *f, char *name)
+{
+	ITEM *t;
+	bool *ret;
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return 0;
+	}
+
+	t = CfgFindItem(f, name);
+	if (t == NULL)
+	{
+		return 0;
+	}
+	if (t->Type != ITEM_TYPE_BOOL)
+	{
+		return 0;
+	}
+	if (t->size != sizeof(bool))
+	{
+		return 0;
+	}
+
+	ret = (bool *)t->Buf;
+	if (*ret == false)
+	{
+		return false;
+	}
+	else
+	{
+		return true;
+	}
+}
+
+// int 型の値の取得
+UINT CfgGetInt(FOLDER *f, char *name)
+{
+	ITEM *t;
+	UINT *ret;
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return 0;
+	}
+
+	t = CfgFindItem(f, name);
+	if (t == NULL)
+	{
+		return 0;
+	}
+	if (t->Type != ITEM_TYPE_INT)
+	{
+		return 0;
+	}
+	if (t->size != sizeof(UINT))
+	{
+		return 0;
+	}
+
+	ret = (UINT *)t->Buf;
+	return *ret;
+}
+
+// アイテムの検索
+ITEM *CfgFindItem(FOLDER *parent, char *name)
+{
+	ITEM *t, tt;
+	// 引数チェック
+	if (parent == NULL || name == NULL)
+	{
+		return NULL;
+	}
+
+	tt.Name = ZeroMalloc(StrLen(name) + 1);
+	StrCpy(tt.Name, 0, name);
+	t = Search(parent->Items, &tt);
+	Free(tt.Name);
+
+	return t;
+}
+
+// フォルダの取得
+FOLDER *CfgGetFolder(FOLDER *parent, char *name)
+{
+	return CfgFindFolder(parent, name);
+}
+
+// フォルダの検索
+FOLDER *CfgFindFolder(FOLDER *parent, char *name)
+{
+	FOLDER *f, ff;
+	// 引数チェック
+	if (parent == NULL || name == NULL)
+	{
+		return NULL;
+	}
+
+	ff.Name = ZeroMalloc(StrLen(name) + 1);
+	StrCpy(ff.Name, 0, name);
+	f = Search(parent->Folders, &ff);
+	Free(ff.Name);
+
+	return f;
+}
+
+// string 型の追加
+ITEM *CfgAddStr(FOLDER *f, char *name, char *str)
+{
+	wchar_t *tmp;
+	UINT tmp_size;
+	ITEM *t;
+	// 引数チェック
+	if (f == NULL || name == NULL || str == NULL)
+	{
+		return NULL;
+	}
+
+	// Unicode 文字列に変換
+	tmp_size = CalcStrToUni(str);
+	if (tmp_size == 0)
+	{
+		return NULL;
+	}
+	tmp = Malloc(tmp_size);
+	StrToUni(tmp, tmp_size, str);
+	t = CfgAddUniStr(f, name, tmp);
+	Free(tmp);
+
+	return t;
+}
+
+// unicode_string 型の追加
+ITEM *CfgAddUniStr(FOLDER *f, char *name, wchar_t *str)
+{
+	// 引数チェック
+	if (f == NULL || name == NULL || str == NULL)
+	{
+		return NULL;
+	}
+
+	return CfgCreateItem(f, name, ITEM_TYPE_STRING, str, UniStrSize(str));
+}
+
+// バイナリの追加
+ITEM *CfgAddBuf(FOLDER *f, char *name, BUF *b)
+{
+	// 引数チェック
+	if (f == NULL || name == NULL || b == NULL)
+	{
+		return NULL;
+	}
+	return CfgAddByte(f, name, b->Buf, b->Size);
+}
+
+// バイト型の追加
+ITEM *CfgAddByte(FOLDER *f, char *name, void *buf, UINT size)
+{
+	// 引数チェック
+	if (f == NULL || name == NULL || buf == NULL)
+	{
+		return NULL;
+	}
+	return CfgCreateItem(f, name, ITEM_TYPE_BYTE, buf, size);
+}
+
+// 64bit 整数型の追加
+ITEM *CfgAddInt64(FOLDER *f, char *name, UINT64 i)
+{
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return NULL;
+	}
+	return CfgCreateItem(f, name, ITEM_TYPE_INT64, &i, sizeof(UINT64));
+}
+
+// IP アドレス型の取得
+bool CfgGetIp(FOLDER *f, char *name, struct IP *ip)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (f == NULL || name == NULL || ip == NULL)
+	{
+		return false;
+	}
+
+	Zero(ip, sizeof(IP));
+
+	if (CfgGetStr(f, name, tmp, sizeof(tmp)) == false)
+	{
+		return false;
+	}
+
+	if (StrToIP(ip, tmp) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+UINT CfgGetIp32(FOLDER *f, char *name)
+{
+	IP p;
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return 0;
+	}
+
+	if (CfgGetIp(f, name, &p) == false)
+	{
+		return 0;
+	}
+
+	return IPToUINT(&p);
+}
+bool CfgGetIp6Addr(FOLDER *f, char *name, IPV6_ADDR *addr)
+{
+	IP ip;
+	// 引数チェック
+	Zero(addr, sizeof(IPV6_ADDR));
+	if (f == NULL || name == NULL || addr == NULL)
+	{
+		return false;
+	}
+
+	if (CfgGetIp(f, name, &ip) == false)
+	{
+		return false;
+	}
+
+	if (IsIP6(&ip) == false)
+	{
+		return false;
+	}
+
+	if (IPToIPv6Addr(addr, &ip) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// IP アドレス型の追加
+ITEM *CfgAddIp(FOLDER *f, char *name, struct IP *ip)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (f == NULL || name == NULL || ip == NULL)
+	{
+		return NULL;
+	}
+
+	IPToStr(tmp, sizeof(tmp), ip);
+
+	return CfgAddStr(f, name, tmp);
+}
+ITEM *CfgAddIp32(FOLDER *f, char *name, UINT ip)
+{
+	IP p;
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return NULL;
+	}
+
+	UINTToIP(&p, ip);
+
+	return CfgAddIp(f, name, &p);
+}
+ITEM *CfgAddIp6Addr(FOLDER *f, char *name, IPV6_ADDR *addr)
+{
+	IP ip;
+	// 引数チェック
+	if (f == NULL || name == NULL || addr == NULL)
+	{
+		return NULL;
+	}
+
+	IPv6AddrToIP(&ip, addr);
+
+	return CfgAddIp(f, name, &ip);
+}
+
+// 整数型の追加
+ITEM *CfgAddInt(FOLDER *f, char *name, UINT i)
+{
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return NULL;
+	}
+	return CfgCreateItem(f, name, ITEM_TYPE_INT, &i, sizeof(UINT));
+}
+
+// bool 型の追加
+ITEM *CfgAddBool(FOLDER *f, char *name, bool b)
+{
+	bool v;
+	// 引数チェック
+	if (f == NULL || name == NULL)
+	{
+		return NULL;
+	}
+
+	v = b ? 1 : 0;
+	return CfgCreateItem(f, name, ITEM_TYPE_BOOL, &b, sizeof(bool));
+}
+
+// アイテム名の比較関数
+int CmpItemName(void *p1, void *p2)
+{
+	ITEM *f1, *f2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	f1 = *(ITEM **)p1;
+	f2 = *(ITEM **)p2;
+	if (f1 == NULL || f2 == NULL)
+	{
+		return 0;
+	}
+	return StrCmpi(f1->Name, f2->Name);
+}
+
+// フォルダ名の比較関数
+int CmpFolderName(void *p1, void *p2)
+{
+	FOLDER *f1, *f2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	f1 = *(FOLDER **)p1;
+	f2 = *(FOLDER **)p2;
+	if (f1 == NULL || f2 == NULL)
+	{
+		return 0;
+	}
+	return StrCmpi(f1->Name, f2->Name);
+}
+
+// アイテムの列挙
+void CfgEnumItem(FOLDER *f, ENUM_ITEM proc, void *param)
+{
+	UINT i;
+	// 引数チェック
+	if (f == NULL || proc == NULL)
+	{
+		return;
+	}
+	
+	for (i = 0;i < LIST_NUM(f->Items);i++)
+	{
+		ITEM *tt = LIST_DATA(f->Items, i);
+		if (proc(tt, param) == false)
+		{
+			break;
+		}
+	}
+}
+
+// フォルダを列挙してトークンリストに格納
+TOKEN_LIST *CfgEnumFolderToTokenList(FOLDER *f)
+{
+	TOKEN_LIST *t, *ret;
+	UINT i;
+	// 引数チェック
+	if (f == NULL)
+	{
+		return NULL;
+	}
+
+	t = ZeroMalloc(sizeof(TOKEN_LIST));
+	t->NumTokens = LIST_NUM(f->Folders);
+	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		FOLDER *ff = LIST_DATA(f->Folders, i);
+		t->Token[i] = CopyStr(ff->Name);
+	}
+
+	ret = UniqueToken(t);
+	FreeToken(t);
+
+	return ret;
+}
+
+// アイテムを列挙してトークンリストに格納
+TOKEN_LIST *CfgEnumItemToTokenList(FOLDER *f)
+{
+	TOKEN_LIST *t, *ret;
+	UINT i;
+	// 引数チェック
+	if (f == NULL)
+	{
+		return NULL;
+	}
+
+	t = ZeroMalloc(sizeof(TOKEN_LIST));
+	t->NumTokens = LIST_NUM(f->Items);
+	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		FOLDER *ff = LIST_DATA(f->Items, i);
+		t->Token[i] = CopyStr(ff->Name);
+	}
+
+	ret = UniqueToken(t);
+	FreeToken(t);
+
+	return ret;
+}
+
+// フォルダの列挙
+void CfgEnumFolder(FOLDER *f, ENUM_FOLDER proc, void *param)
+{
+	UINT i;
+	// 引数チェック
+	if (f == NULL || proc == NULL)
+	{
+		return;
+	}
+	
+	for (i = 0;i < LIST_NUM(f->Folders);i++)
+	{
+		FOLDER *ff = LIST_DATA(f->Folders, i);
+		if (proc(ff, param) == false)
+		{
+			break;
+		}
+
+		if ((i % 100) == 99)
+		{
+			YieldCpu();
+		}
+	}
+}
+
+// アイテムの作成
+ITEM *CfgCreateItem(FOLDER *parent, char *name, UINT type, void *buf, UINT size)
+{
+	UINT name_size;
+	ITEM *t;
+#ifdef	CHECK_CFG_NAME_EXISTS
+	ITEM tt;
+#endif	// CHECK_CFG_NAME_EXISTS
+	// 引数チェック
+	if (parent == NULL || name == NULL || type == 0 || buf == NULL)
+	{
+		return NULL;
+	}
+
+	name_size = StrLen(name) + 1;
+
+#ifdef	CHECK_CFG_NAME_EXISTS
+
+	// すでに同名のアイテムが無いかどうか確認
+	tt.Name = ZeroMalloc(name_size);
+	StrCpy(tt.Name, 0, name);
+	t = Search(parent->Items, &tt);
+	Free(tt.Name);
+	if (t != NULL)
+	{
+		// 重複している
+		return NULL;
+	}
+
+#endif	// CHECK_CFG_NAME_EXISTS
+
+	t = ZeroMalloc(sizeof(ITEM));
+	t->Buf = Malloc(size);
+	Copy(t->Buf, buf, size);
+	t->Name = ZeroMalloc(name_size);
+	StrCpy(t->Name, 0, name);
+	t->Type = type;
+	t->size = size;
+	t->Parent = parent;
+	
+	// 親のリストに追加
+	Insert(parent->Items, t);
+
+	return t;
+}
+
+// アイテムの削除
+void CfgDeleteItem(ITEM *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	// 親のリストから削除
+	Delete(t->Parent->Items, t);
+
+	// メモリ解放
+	Free(t->Buf);
+	Free(t->Name);
+	Free(t);
+}
+
+
+// フォルダの削除
+void CfgDeleteFolder(FOLDER *f)
+{
+	FOLDER **ff;
+	ITEM **tt;
+	UINT num, i;
+	// 引数チェック
+	if (f == NULL)
+	{
+		return;
+	}
+
+	// サブフォルダをすべて削除
+	num = LIST_NUM(f->Folders);
+	ff = Malloc(sizeof(FOLDER *) * num);
+	Copy(ff, f->Folders->p, sizeof(FOLDER *) * num);
+	for (i = 0;i < num;i++)
+	{
+		CfgDeleteFolder(ff[i]);
+	}
+	Free(ff);
+
+	// アイテムをすべて削除
+	num = LIST_NUM(f->Items);
+	tt = Malloc(sizeof(ITEM *) * num);
+	Copy(tt, f->Items->p, sizeof(ITEM *) * num);
+	for (i = 0;i < num;i++)
+	{
+		CfgDeleteItem(tt[i]);
+	}
+	Free(tt);
+
+	// メモリ解放
+	Free(f->Name);
+	// 親のリストから削除
+	if (f->Parent != NULL)
+	{
+		Delete(f->Parent->Folders, f);
+	}
+	// リストの解放
+	ReleaseList(f->Folders);
+	ReleaseList(f->Items);
+
+	// 本体のメモリの解放
+	Free(f);
+}
+
+// ルートの作成
+FOLDER *CfgCreateRoot()
+{
+	return CfgCreateFolder(NULL, TAG_ROOT);
+}
+
+// フォルダの作成
+FOLDER *CfgCreateFolder(FOLDER *parent, char *name)
+{
+	UINT size;
+	FOLDER *f;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	size = StrLen(name) + 1;
+
+#ifdef	CHECK_CFG_NAME_EXISTS
+
+	// 親のリストの名前を検査
+	if (parent != NULL)
+	{
+		FOLDER ff;
+		ff.Name = ZeroMalloc(size);
+		StrCpy(ff.Name, 0, name);
+		f = Search(parent->Folders, &ff);
+		Free(ff.Name);
+		if (f != NULL)
+		{
+			// 既に同じ名前のフォルダが存在する
+			return NULL;
+		}
+	}
+
+#endif	// CHECK_CFG_NAME_EXISTS
+
+	f = ZeroMalloc(sizeof(FOLDER));
+	f->Items = NewListFast(CmpItemName);
+	f->Folders = NewListFast(CmpFolderName);
+	f->Name = ZeroMalloc(size);
+	StrCpy(f->Name, 0, name);
+	f->Parent = parent;
+
+	// 親のリストに追加
+	if (f->Parent != NULL)
+	{
+		Insert(f->Parent->Folders, f);
+	}
+	return f;
+}
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Cfg.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Cfg.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Cfg.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,239 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Cfg.h
+// Cfg.c のヘッダ
+
+#ifndef	CFG_H
+#define	CFG_H
+
+// マクロ
+//#define	CHECK_CFG_NAME_EXISTS			// 既存の名前との重複チェックを行う
+
+#define	SAVE_BINARY_FILE_NAME_SWITCH	L"@save_binary"
+
+// 定数
+#define	TAG_DECLARE			"declare"
+#define	TAG_STRING			"string"
+#define	TAG_INT				"uint"
+#define	TAG_INT64			"uint64"
+#define	TAG_BOOL			"bool"
+#define	TAG_BYTE			"byte"
+#define	TAG_TRUE			"true"
+#define	TAG_FALSE			"false"
+#define	TAG_END				"end"
+#define	TAG_ROOT			"root"
+
+#define	TAG_CPYRIGHT		"\xef\xbb\xbf# SoftEther UT-VPN Software Configuration File\r\n# \r\n# You can edit this file when the program is not working.\r\n# \r\n"
+#define	TAG_BINARY			"SEVPN_DB"
+
+// データ型
+#define	ITEM_TYPE_INT		1		// int
+#define	ITEM_TYPE_INT64		2		// int64
+#define	ITEM_TYPE_BYTE		3		// byte
+#define	ITEM_TYPE_STRING	4		// string
+#define	ITEM_TYPE_BOOL		5		// bool
+
+// フォルダ
+struct FOLDER
+{
+	char *Name;				// フォルダ名
+	LIST *Items;			// アイテムのリスト
+	LIST *Folders;			// サブフォルダ
+	struct FOLDER *Parent;	// 親フォルダ
+};
+
+// アイテム
+struct ITEM
+{
+	char *Name;				// アイテム名
+	UINT Type;				// データ型
+	void *Buf;				// データ
+	UINT size;				// データサイズ
+	FOLDER *Parent;			// 親フォルダ
+};
+
+// 設定ファイルリーダライタ
+struct CFG_RW
+{
+	LOCK *lock;				// ロック
+	char *FileName;			// ファイル名 (ANSI)
+	wchar_t *FileNameW;		// ファイル名 (Unicode)
+	IO *Io;					// IO
+	UCHAR LashHash[SHA1_SIZE];	// 最後に書き込んだハッシュ値
+	bool DontBackup;		// バックアップを使用しない
+};
+
+typedef bool (*ENUM_FOLDER)(FOLDER *f, void *param);
+typedef bool (*ENUM_ITEM)(ITEM *t, void *param);
+
+// 列挙用のパラメータ
+struct CFG_ENUM_PARAM
+{
+	BUF *b;
+	FOLDER *f;
+	UINT depth;
+};
+
+int CmpItemName(void *p1, void *p2);
+int CmpFolderName(void *p1, void *p2);
+ITEM *CfgCreateItem(FOLDER *parent, char *name, UINT type, void *buf, UINT size);
+void CfgDeleteFolder(FOLDER *f);
+FOLDER *CfgCreateFolder(FOLDER *parent, char *name);
+void CfgEnumFolder(FOLDER *f, ENUM_FOLDER proc, void *param);
+TOKEN_LIST *CfgEnumFolderToTokenList(FOLDER *f);
+TOKEN_LIST *CfgEnumItemToTokenList(FOLDER *f);
+void CfgEnumItem(FOLDER *f, ENUM_ITEM proc, void *param);
+FOLDER *CfgFindFolder(FOLDER *parent, char *name);
+ITEM *CfgFindItem(FOLDER *parent, char *name);
+ITEM *CfgAddInt(FOLDER *f, char *name, UINT i);
+ITEM *CfgAddBool(FOLDER *f, char *name, bool b);
+ITEM *CfgAddInt64(FOLDER *f, char *name, UINT64 i);
+ITEM *CfgAddByte(FOLDER *f, char *name, void *buf, UINT size);
+ITEM *CfgAddBuf(FOLDER *f, char *name, BUF *b);
+ITEM *CfgAddStr(FOLDER *f, char *name, char *str);
+ITEM *CfgAddUniStr(FOLDER *f, char *name, wchar_t *str);
+FOLDER *CfgGetFolder(FOLDER *parent, char *name);
+UINT CfgGetInt(FOLDER *f, char *name);
+bool CfgGetBool(FOLDER *f, char *name);
+UINT64 CfgGetInt64(FOLDER *f, char *name);
+UINT CfgGetByte(FOLDER *f, char *name, void *buf, UINT size);
+BUF *CfgGetBuf(FOLDER *f, char *name);
+bool CfgGetStr(FOLDER *f, char *name, char *str, UINT size);
+bool CfgGetUniStr(FOLDER *f, char *name, wchar_t *str, UINT size);
+bool CfgIsItem(FOLDER *f, char *name);
+bool CfgIsFolder(FOLDER *f, char *name);
+void CfgTest();
+void CfgTest2(FOLDER *f, UINT n);
+char *CfgEscape(char *name);
+bool CfgCheckCharForName(char c);
+char *CfgUnescape(char *str);
+BUF *CfgFolderToBuf(FOLDER *f, bool textmode);
+BUF *CfgFolderToBufEx(FOLDER *f, bool textmode, bool no_banner);
+BUF *CfgFolderToBufText(FOLDER *f);
+BUF *CfgFolderToBufTextEx(FOLDER *f, bool no_banner);
+BUF *CfgFolderToBufBin(FOLDER *f);
+void CfgOutputFolderText(BUF *b, FOLDER *f, UINT depth);
+void CfgOutputFolderBin(BUF *b, FOLDER *f);
+void CfgAddLine(BUF *b, char *str, UINT depth);
+void CfgAddDeclare(BUF *b, char *name, UINT depth);
+void CfgAddEnd(BUF *b, UINT depth);
+void CfgAddData(BUF *b, UINT type, char *name, char *data, char *sub, UINT depth);
+UINT CfgStrToType(char *str);
+char *CfgTypeToStr(UINT type);
+void CfgAddItemText(BUF *b, ITEM *t, UINT depth);
+bool CfgEnumFolderProc(FOLDER *f, void *param);
+bool CfgEnumItemProc(ITEM *t, void *param);
+FOLDER *CfgBufTextToFolder(BUF *b);
+FOLDER *CfgBufBinToFolder(BUF *b);
+void CfgReadNextFolderBin(BUF *b, FOLDER *parent);
+char *CfgReadNextLine(BUF *b);
+bool CfgReadNextTextBuf(BUF *b, FOLDER *current);
+void CfgSave(FOLDER *f, char *name);
+void CfgSaveW(FOLDER *f, wchar_t *name);
+bool CfgSaveEx(CFG_RW *rw, FOLDER *f, char *name);
+bool CfgSaveExW(CFG_RW *rw, FOLDER *f, wchar_t *name);
+bool CfgSaveExW2(CFG_RW *rw, FOLDER *f, wchar_t *name, UINT *written_size);
+FOLDER *CfgRead(char *name);
+FOLDER *CfgReadW(wchar_t *name);
+FOLDER *CfgCreateRoot();
+void CfgTest();
+void CfgTest2(FOLDER *f, UINT n);
+CFG_RW *NewCfgRw(FOLDER **root, char *cfg_name);
+CFG_RW *NewCfgRwW(FOLDER **root, wchar_t *cfg_name);
+CFG_RW *NewCfgRwEx(FOLDER **root, char *cfg_name, bool dont_backup);
+CFG_RW *NewCfgRwExW(FOLDER **root, wchar_t *cfg_name, bool dont_backup);
+UINT SaveCfgRw(CFG_RW *rw, FOLDER *f);
+void FreeCfgRw(CFG_RW *rw);
+ITEM *CfgAddIp32(FOLDER *f, char *name, UINT ip);
+UINT CfgGetIp32(FOLDER *f, char *name);
+bool CfgGetIp6Addr(FOLDER *f, char *name, IPV6_ADDR *addr);
+ITEM *CfgAddIp6Addr(FOLDER *f, char *name, IPV6_ADDR *addr);
+bool FileCopy(char *src, char *dst);
+bool FileCopyW(wchar_t *src, wchar_t *dst);
+void BackupCfg(FOLDER *f, char *original);
+void BackupCfgW(FOLDER *f, wchar_t *original);
+
+#if	(!defined(CFG_C)) || (!defined(OS_UNIX))
+bool CfgGetIp(FOLDER *f, char *name, struct IP *ip);
+ITEM *CfgAddIp(FOLDER *f, char *name, struct IP *ip);
+#endif
+
+#endif	// CFG_H
+
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Encrypt.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Encrypt.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Encrypt.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,3545 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Encrypt.c
+// 暗号化および電子証明書ルーチン
+
+#define	ENCRYPT_C
+
+#define	__WINCRYPT_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/engine.h>
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rc4.h>
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <Mayaqua/Mayaqua.h>
+
+LOCK *openssl_lock = NULL;
+
+LOCK **ssl_lock_obj = NULL;
+UINT ssl_lock_num;
+static bool openssl_inited = false;
+
+// コールバック関数用
+typedef struct CB_PARAM
+{
+	char *password;
+} CB_PARAM;
+
+// 証明書が特定のディレクトリの CRL によって無効化されているかどうか確認する
+bool IsXRevoked(X *x)
+{
+	char dirname[MAX_PATH];
+	UINT i;
+	bool ret = false;
+	DIRLIST *t;
+	// 引数チェック
+	if (x == NULL)
+	{
+		return false;
+	}
+
+	GetExeDir(dirname, sizeof(dirname));
+
+	// CRL ファイルの検索
+	t = EnumDir(dirname);
+
+	for (i = 0;i < t->NumFiles;i++)
+	{
+		char *name = t->File[i]->FileName;
+		if (t->File[i]->Folder == false)
+		{
+			if (EndWith(name, ".crl"))
+			{
+				char filename[MAX_PATH];
+				X_CRL *r;
+
+				ConbinePath(filename, sizeof(filename), dirname, name);
+
+				r = FileToXCrl(filename);
+
+				if (r != NULL)
+				{
+					if (IsXRevokedByXCrl(x, r))
+					{
+						ret = true;
+					}
+
+					FreeXCrl(r);
+				}
+			}
+		}
+	}
+
+	FreeDir(t);
+
+	return ret;
+}
+
+// 証明書が CRL によって無効化されているかどうか確認する
+bool IsXRevokedByXCrl(X *x, X_CRL *r)
+{
+#ifdef	OS_WIN32
+	X509_REVOKED tmp;
+	X509_CRL_INFO *info;
+	int index;
+	// 引数チェック
+	if (x == NULL || r == NULL)
+	{
+		return false;
+	}
+
+	Zero(&tmp, sizeof(tmp));
+	tmp.serialNumber = X509_get_serialNumber(x->x509);
+
+	info = r->Crl->crl;
+
+	if (sk_X509_REVOKED_is_sorted(info->revoked) == false)
+	{
+		sk_X509_REVOKED_sort(info->revoked);
+	}
+
+	index = sk_X509_REVOKED_find(info->revoked, &tmp);
+
+	if (index < 0)
+	{
+		return false;
+	}
+	else
+	{
+		return true;
+	}
+#else	// OS_WIN32
+	return false;
+#endif	// OS_WIN32
+}
+
+// CRL の解放
+void FreeXCrl(X_CRL *r)
+{
+	// 引数チェック
+	if (r == NULL)
+	{
+		return;
+	}
+
+	X509_CRL_free(r->Crl);
+
+	Free(r);
+}
+
+// ファイルを CRL に変換
+X_CRL *FileToXCrl(char *filename)
+{
+	wchar_t *filename_w = CopyStrToUni(filename);
+	X_CRL *ret = FileToXCrlW(filename_w);
+
+	Free(filename_w);
+
+	return ret;
+}
+X_CRL *FileToXCrlW(wchar_t *filename)
+{
+	BUF *b;
+	X_CRL *r;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return NULL;
+	}
+
+	b = ReadDumpW(filename);
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	r = BufToXCrl(b);
+
+	FreeBuf(b);
+
+	return r;
+}
+
+// バッファを CRL に変換
+X_CRL *BufToXCrl(BUF *b)
+{
+	X_CRL *r;
+	X509_CRL *x509crl;
+	BIO *bio;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	bio = BufToBio(b);
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	x509crl	= NULL;
+
+	if (d2i_X509_CRL_bio(bio, &x509crl) == NULL || x509crl == NULL)
+	{
+		FreeBio(bio);
+		return NULL;
+	}
+
+	r = ZeroMalloc(sizeof(X_CRL));
+	r->Crl = x509crl;
+
+	FreeBio(bio);
+
+	return r;
+}
+
+// バッファを公開鍵に変換
+K *RsaBinToPublic(void *data, UINT size)
+{
+	RSA *rsa;
+	K *k;
+	BIO *bio;
+	// 引数チェック
+	if (data == NULL || size < 4)
+	{
+		return NULL;
+	}
+
+	rsa = RSA_new();
+
+	if (rsa->e != NULL)
+	{
+		BN_free(rsa->e);
+	}
+
+	rsa->e = BN_new();
+	BN_set_word(rsa->e, RSA_F4);
+
+	if (rsa->n != NULL)
+	{
+		BN_free(rsa->n);
+	}
+
+	rsa->n = BinToBigNum(data, size);
+
+	bio = NewBio();
+	Lock(openssl_lock);
+	{
+		i2d_RSA_PUBKEY_bio(bio, rsa);
+	}
+	Unlock(openssl_lock);
+	BIO_seek(bio, 0);
+	k = BioToK(bio, false, false, NULL);
+	FreeBio(bio);
+
+	RSA_free(rsa);
+
+	return k;
+}
+
+// 公開鍵をバッファに変換
+BUF *RsaPublicToBuf(K *k)
+{
+	BUF *b;
+	// 引数チェック
+	if (k == NULL || k->pkey == NULL || k->pkey->pkey.rsa == NULL
+		|| k->pkey->pkey.rsa->n == NULL)
+	{
+		return NULL;
+	}
+
+	b = BigNumToBuf(k->pkey->pkey.rsa->n);
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	return b;
+}
+
+// 公開鍵をバイナリに変換
+void RsaPublicToBin(K *k, void *data)
+{
+	BUF *b;
+	// 引数チェック
+	if (k == NULL || k->pkey == NULL || k->pkey->pkey.rsa == NULL
+		|| k->pkey->pkey.rsa->n == NULL || data == NULL)
+	{
+		return;
+	}
+
+	b = BigNumToBuf(k->pkey->pkey.rsa->n);
+	if (b == NULL)
+	{
+		return;
+	}
+
+	Copy(data, b->Buf, b->Size);
+
+	FreeBuf(b);
+}
+
+// 公開鍵サイズの取得
+UINT RsaPublicSize(K *k)
+{
+	BUF *b;
+	UINT ret;
+	// 引数チェック
+	if (k == NULL || k->pkey == NULL || k->pkey->pkey.rsa == NULL
+		|| k->pkey->pkey.rsa->n == NULL)
+	{
+		return 0;
+	}
+
+	b = BigNumToBuf(k->pkey->pkey.rsa->n);
+	if (b == NULL)
+	{
+		return 0;
+	}
+
+	ret = b->Size;
+
+	FreeBuf(b);
+
+	return ret;
+}
+
+// ポインタを 32 ビットにハッシュする
+UINT HashPtrToUINT(void *p)
+{
+	UCHAR hash_data[MD5_SIZE];
+	UINT ret;
+	// 引数チェック
+	if (p == NULL)
+	{
+		return 0;
+	}
+
+	Hash(hash_data, &p, sizeof(p), false);
+
+	Copy(&ret, hash_data, sizeof(ret));
+
+	return ret;
+}
+
+// NAME のコピー
+NAME *CopyName(NAME *n)
+{
+	// 引数チェック
+	if (n == NULL)
+	{
+		return NULL;
+	}
+
+	return NewName(n->CommonName, n->Organization, n->Unit,
+		n->Country, n->State, n->Local);
+}
+
+// バイナリを BIGNUM に変換
+BIGNUM *BinToBigNum(void *data, UINT size)
+{
+	BIGNUM *bn;
+	// 引数チェック
+	if (data == NULL)
+	{
+		return NULL;
+	}
+
+	bn = BN_new();
+	BN_bin2bn(data, size, bn);
+
+	return bn;
+}
+
+// バッファを BIGNUM に変換
+BIGNUM *BufToBigNum(BUF *b)
+{
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	return BinToBigNum(b->Buf, b->Size);
+}
+
+// BIGNUM をバッファに変換
+BUF *BigNumToBuf(BIGNUM *bn)
+{
+	UINT size;
+	UCHAR *tmp;
+	BUF *b;
+	// 引数チェック
+	if (bn == NULL)
+	{
+		return NULL;
+	}
+
+	size = BN_num_bytes(bn);
+	tmp = ZeroMalloc(size);
+	BN_bn2bin(bn, tmp);
+
+	b = NewBuf();
+	WriteBuf(b, tmp, size);
+	Free(tmp);
+
+	SeekBuf(b, 0, 0);
+
+	return b;
+}
+
+// OpenSSL のロックの初期化
+void OpenSSL_InitLock()
+{
+	UINT i;
+
+	// ロックオブジェクトの初期化
+	ssl_lock_num = CRYPTO_num_locks();
+	ssl_lock_obj = Malloc(sizeof(LOCK *) * ssl_lock_num);
+	for (i = 0;i < ssl_lock_num;i++)
+	{
+		ssl_lock_obj[i] = NewLock();
+	}
+
+	// ロック関数の設定
+	CRYPTO_set_locking_callback(OpenSSL_Lock);
+	CRYPTO_set_id_callback(OpenSSL_Id);
+}
+
+// OpenSSL のロックの解放
+void OpenSSL_FreeLock()
+{
+	UINT i;
+
+	for (i = 0;i < ssl_lock_num;i++)
+	{
+		DeleteLock(ssl_lock_obj[i]);
+	}
+	Free(ssl_lock_obj);
+	ssl_lock_obj = NULL;
+
+	CRYPTO_set_locking_callback(NULL);
+	CRYPTO_set_id_callback(NULL);
+}
+
+// OpenSSL のロック関数
+void OpenSSL_Lock(int mode, int n, const char *file, int line)
+{
+	LOCK *lock = ssl_lock_obj[n];
+
+	if (mode & CRYPTO_LOCK)
+	{
+		// ロック
+		Lock(lock);
+	}
+	else
+	{
+		// ロック解除
+		Unlock(lock);
+	}
+}
+
+// スレッド ID の返却
+unsigned long OpenSSL_Id(void)
+{
+	return (unsigned long)ThreadId();
+}
+
+// 証明書の表示名を取得
+void GetPrintNameFromX(wchar_t *str, UINT size, X *x)
+{
+	// 引数チェック
+	if (x == NULL || str == NULL)
+	{
+		return;
+	}
+
+	GetPrintNameFromName(str, size, x->subject_name);
+}
+void GetPrintNameFromXA(char *str, UINT size, X *x)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL || x == NULL)
+	{
+		return;
+	}
+
+	GetPrintNameFromX(tmp, sizeof(tmp), x);
+
+	UniToStr(str, size, tmp);
+}
+void GetAllNameFromXEx(wchar_t *str, UINT size, X *x)
+{
+	// 引数チェック
+	if (x == NULL || str == NULL)
+	{
+		return;
+	}
+
+	GetAllNameFromNameEx(str, size, x->subject_name);
+}
+void GetAllNameFromXExA(char *str, UINT size, X *x)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL || x == NULL)
+	{
+		return;
+	}
+
+	GetAllNameFromXEx(tmp, sizeof(tmp), x);
+
+	UniToStr(str, size, tmp);
+}
+
+// NAME から表示名を取得
+void GetPrintNameFromName(wchar_t *str, UINT size, NAME *name)
+{
+	// 引数チェック
+	if (str == NULL || name == NULL)
+	{
+		return;
+	}
+
+	if (name->CommonName != NULL)
+	{
+		UniStrCpy(str, size, name->CommonName);
+	}
+	else if (name->Organization != NULL)
+	{
+		UniStrCpy(str, size, name->Organization);
+	}
+	else if (name->Unit != NULL)
+	{
+		UniStrCpy(str, size, name->Unit);
+	}
+	else if (name->State != NULL)
+	{
+		UniStrCpy(str, size, name->State);
+	}
+	else if (name->Local != NULL)
+	{
+		UniStrCpy(str, size, name->Local);
+	}
+	else if (name->Country != NULL)
+	{
+		UniStrCpy(str, size, name->Country);
+	}
+	else
+	{
+		UniStrCpy(str, size, L"untitled");
+	}
+}
+
+// 証明書からすべての名前文字列を取得
+void GetAllNameFromX(wchar_t *str, UINT size, X *x)
+{
+	UCHAR md5[MD5_SIZE], sha1[SHA1_SIZE];
+	char tmp1[MD5_SIZE * 3 + 8], tmp2[SHA1_SIZE * 3 + 8];
+	wchar_t tmp3[sizeof(tmp1) + sizeof(tmp2) + 64];
+	// 引数チェック
+	if (str == NULL || x == NULL)
+	{
+		return;
+	}
+
+	GetAllNameFromName(str, size, x->subject_name);
+
+	if (x->serial != NULL && x->serial->size >= 1)
+	{
+		char tmp[128];
+		wchar_t tmp2[128];
+
+		BinToStr(tmp, sizeof(tmp), x->serial->data, x->serial->size);
+		UniFormat(tmp2, sizeof(tmp2), L", SERIAL=\"%S\"", tmp);
+
+		UniStrCat(str, size, tmp2);
+	}
+
+	// ダイジェスト値
+	GetXDigest(x, md5, false);
+	GetXDigest(x, sha1, true);
+
+	BinToStr(tmp1, sizeof(tmp1), md5, MD5_SIZE);
+	BinToStr(tmp2, sizeof(tmp2), sha1, SHA1_SIZE);
+
+	UniFormat(tmp3, sizeof(tmp3), L" (Digest: MD5=\"%S\", SHA1=\"%S\")", tmp1, tmp2);
+	UniStrCat(str, size, tmp3);
+}
+void GetAllNameFromA(char *str, UINT size, X *x)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL || x == NULL)
+	{
+		return;
+	}
+
+	GetAllNameFromX(tmp, sizeof(tmp), x);
+	UniToStr(str, size, tmp);
+}
+
+// NAME からすべての名前文字列を取得
+void GetAllNameFromName(wchar_t *str, UINT size, NAME *name)
+{
+	// 引数チェック
+	if (str == NULL || name == NULL)
+	{
+		return;
+	}
+
+	UniStrCpy(str, size, L"");
+	if (name->CommonName != NULL)
+	{
+		UniFormat(str, size, L"%sCN=%s, ", str, name->CommonName);
+	}
+	if (name->Organization != NULL)
+	{
+		UniFormat(str, size, L"%sO=%s, ", str, name->Organization);
+	}
+	if (name->Unit != NULL)
+	{
+		UniFormat(str, size, L"%sOU=%s, ", str, name->Unit);
+	}
+	if (name->State != NULL)
+	{
+		UniFormat(str, size, L"%sS=%s, ", str, name->State);
+	}
+	if (name->Local != NULL)
+	{
+		UniFormat(str, size, L"%sL=%s, ", str, name->Local);
+	}
+	if (name->Country != NULL)
+	{
+		UniFormat(str, size, L"%sC=%s, ", str, name->Country);
+	}
+
+	if (UniStrLen(str) >= 3)
+	{
+		UINT len = UniStrLen(str);
+		if (str[len - 2] == L',' &&
+			str[len - 1] == L' ')
+		{
+			str[len - 2] = 0;
+		}
+	}
+}
+void GetAllNameFromNameEx(wchar_t *str, UINT size, NAME *name)
+{
+	// 引数チェック
+	if (str == NULL || name == NULL)
+	{
+		return;
+	}
+
+	UniStrCpy(str, size, L"");
+	if (name->CommonName != NULL)
+	{
+		UniFormat(str, size, L"%s%s, ", str, name->CommonName);
+	}
+	if (name->Organization != NULL)
+	{
+		UniFormat(str, size, L"%s%s, ", str, name->Organization);
+	}
+	if (name->Unit != NULL)
+	{
+		UniFormat(str, size, L"%s%s, ", str, name->Unit);
+	}
+	if (name->State != NULL)
+	{
+		UniFormat(str, size, L"%s%s, ", str, name->State);
+	}
+	if (name->Local != NULL)
+	{
+		UniFormat(str, size, L"%s%s, ", str, name->Local);
+	}
+	if (name->Country != NULL)
+	{
+		UniFormat(str, size, L"%s%s, ", str, name->Country);
+	}
+
+	if (UniStrLen(str) >= 3)
+	{
+		UINT len = UniStrLen(str);
+		if (str[len - 2] == L',' &&
+			str[len - 1] == L' ')
+		{
+			str[len - 2] = 0;
+		}
+	}
+}
+
+// 鍵のクローン
+K *CloneK(K *k)
+{
+	BUF *b;
+	K *ret;
+	// 引数チェック
+	if (k == NULL)
+	{
+		return NULL;
+	}
+
+	b = KToBuf(k, false, NULL);
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	ret = BufToK(b, k->private_key, false, NULL);
+	FreeBuf(b);
+
+	return ret;
+}
+
+// 証明書のクローン
+X *CloneX(X *x)
+{
+	BUF *b;
+	X *ret;
+	// 引数チェック
+	if (x == NULL)
+	{
+		return NULL;
+	}
+
+	b = XToBuf(x, false);
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	ret = BufToX(b, false);
+	FreeBuf(b);
+
+	return ret;
+}
+
+// P12 を生成する
+P12 *NewP12(X *x, K *k, char *password)
+{
+	PKCS12 *pkcs12;
+	P12 *p12;
+	// 引数チェック
+	if (x == NULL || k == NULL)
+	{
+		return false;
+	}
+	if (password && StrLen(password) == 0)
+	{
+		password = NULL;
+	}
+
+	Lock(openssl_lock);
+	{
+		pkcs12 = PKCS12_create(password, NULL, k->pkey, x->x509, NULL, 0, 0, 0, 0, 0);
+		if (pkcs12 == NULL)
+		{
+			Unlock(openssl_lock);
+			return NULL;
+		}
+	}
+	Unlock(openssl_lock);
+
+	p12 = PKCS12ToP12(pkcs12);
+
+	return p12;
+}
+
+// P12 が暗号化されているかどうかチェックする
+bool IsEncryptedP12(P12 *p12)
+{
+	X *x;
+	K *k;
+	// 引数チェック
+	if (p12 == NULL)
+	{
+		return false;
+	}
+
+	if (ParseP12(p12, &x, &k, NULL) == true)
+	{
+		FreeX(x);
+		FreeK(k);
+		return false;
+	}
+
+	return true;
+}
+
+// P12 から X と K を取り出す
+bool ParseP12(P12 *p12, X **x, K **k, char *password)
+{
+	EVP_PKEY *pkey;
+	X509 *x509;
+	// 引数チェック
+	if (p12 == NULL || x == NULL || k == NULL)
+	{
+		return false;
+	}
+	if (password && StrLen(password) == 0)
+	{
+		password = NULL;
+	}
+	if (password == NULL)
+	{
+		password = "";
+	}
+
+	// パスワード確認
+	Lock(openssl_lock);
+	{
+		if (PKCS12_verify_mac(p12->pkcs12, password, -1) == false &&
+			PKCS12_verify_mac(p12->pkcs12, NULL, -1) == false)
+		{
+			Unlock(openssl_lock);
+			return false;
+		}
+	}
+	Unlock(openssl_lock);
+
+	// 抽出
+	Lock(openssl_lock);
+	{
+		if (PKCS12_parse(p12->pkcs12, password, &pkey, &x509, NULL) == false)
+		{
+			if (PKCS12_parse(p12->pkcs12, NULL, &pkey, &x509, NULL) == false)
+			{
+				Unlock(openssl_lock);
+				return false;
+			}
+		}
+	}
+	Unlock(openssl_lock);
+
+	// 変換
+	*x = X509ToX(x509);
+
+	if (*x == NULL)
+	{
+		FreePKey(pkey);
+		return false;
+	}
+
+	*k = ZeroMalloc(sizeof(K));
+	(*k)->private_key = true;
+	(*k)->pkey = pkey;
+
+	return true;
+}
+
+// P12 をファイルに書き出す
+bool P12ToFile(P12 *p12, char *filename)
+{
+	wchar_t *filename_w = CopyStrToUni(filename);
+	bool ret = P12ToFileW(p12, filename_w);
+
+	return ret;
+}
+bool P12ToFileW(P12 *p12, wchar_t *filename)
+{
+	BUF *b;
+	// 引数チェック
+	if (p12 == NULL || filename == NULL)
+	{
+		return false;
+	}
+
+	b = P12ToBuf(p12);
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	if (DumpBufW(b, filename) == false)
+	{
+		FreeBuf(b);
+		return false;
+	}
+
+	FreeBuf(b);
+
+	return true;
+}
+
+// ファイルから P12 を読み込む
+P12 *FileToP12(char *filename)
+{
+	wchar_t *filename_w = CopyStrToUni(filename);
+	P12 *ret = FileToP12W(filename_w);
+
+	Free(filename_w);
+
+	return ret;
+}
+P12 *FileToP12W(wchar_t *filename)
+{
+	BUF *b;
+	P12 *p12;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return NULL;
+	}
+
+	b = ReadDumpW(filename);
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	p12 = BufToP12(b);
+	FreeBuf(b);
+
+	return p12;
+}
+
+// P12 の解放
+void FreeP12(P12 *p12)
+{
+	// 引数チェック
+	if (p12 == NULL)
+	{
+		return;
+	}
+
+	FreePKCS12(p12->pkcs12);
+	Free(p12);
+}
+
+// PKCS12 の解放
+void FreePKCS12(PKCS12 *pkcs12)
+{
+	// 引数チェック
+	if (pkcs12 == NULL)
+	{
+		return;
+	}
+
+	PKCS12_free(pkcs12);
+}
+
+// P12 を BUF に変換する
+BUF *P12ToBuf(P12 *p12)
+{
+	BIO *bio;
+	BUF *buf;
+	// 引数チェック
+	if (p12 == NULL)
+	{
+		return NULL;
+	}
+
+	bio = P12ToBio(p12);
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	buf = BioToBuf(bio);
+	FreeBio(bio);
+
+	SeekBuf(buf, 0, 0);
+
+	return buf;
+}
+
+// P12 を BIO に変換する
+BIO *P12ToBio(P12 *p12)
+{
+	BIO *bio;
+	// 引数チェック
+	if (p12 == NULL)
+	{
+		return NULL;
+	}
+
+	bio = NewBio();
+	Lock(openssl_lock);
+	{
+		i2d_PKCS12_bio(bio, p12->pkcs12);
+	}
+	Unlock(openssl_lock);
+
+	return bio;
+}
+
+// BUF から P12 を読み込む
+P12 *BufToP12(BUF *b)
+{
+	P12 *p12;
+	BIO *bio;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	bio = BufToBio(b);
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	p12 = BioToP12(bio);
+	FreeBio(bio);
+
+	return p12;
+}
+
+// BIO から P12 を読み込む
+P12 *BioToP12(BIO *bio)
+{
+	PKCS12 *pkcs12;
+	// 引数チェック
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	// 変換
+	Lock(openssl_lock);
+	{
+		pkcs12 = d2i_PKCS12_bio(bio, NULL);
+	}
+	Unlock(openssl_lock);
+	if (pkcs12 == NULL)
+	{
+		// 失敗
+		return NULL;
+	}
+
+	return PKCS12ToP12(pkcs12);
+}
+
+// PKCS12 から P12 を生成する
+P12 *PKCS12ToP12(PKCS12 *pkcs12)
+{
+	P12 *p12;
+	// 引数チェック
+	if (pkcs12 == NULL)
+	{
+		return NULL;
+	}
+
+	p12 = ZeroMalloc(sizeof(P12));
+	p12->pkcs12 = pkcs12;
+
+	return p12;
+}
+
+// バイナリを文字列に変換する
+char *ByteToStr(BYTE *src, UINT src_size)
+{
+	UINT size;
+	char *dst;
+	UINT i;
+	// 引数チェック
+	if (src == NULL)
+	{
+		return NULL;
+	}
+
+	size = MAX(src_size * 3, 1);
+	dst = Malloc(size);
+	dst[size - 1] = 0;
+	for (i = 0;i < src_size;i++)
+	{
+		char tmp[3];
+		Format(tmp, sizeof(tmp), "%02x", src[i]);
+		dst[i * 3 + 0] = tmp[0];
+		dst[i * 3 + 1] = tmp[1];
+		dst[i * 3 + 2] = ((i == (src_size - 1) ? 0 : ' '));
+	}
+
+	return dst;
+}
+
+// X_SERIAL の解放
+void FreeXSerial(X_SERIAL *serial)
+{
+	// 引数チェック
+	if (serial == NULL)
+	{
+		return;
+	}
+
+	Free(serial->data);
+	Free(serial);
+}
+
+// X_SERIAL の比較
+bool CompareXSerial(X_SERIAL *s1, X_SERIAL *s2)
+{
+	// 引数チェック
+	if (s1 == NULL || s2 == NULL)
+	{
+		return false;
+	}
+
+	if (s1->size != s2->size)
+	{
+		return false;
+	}
+
+	if (Cmp(s1->data, s2->data, s1->size) != 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// X_SERIAL のコピー
+X_SERIAL *CloneXSerial(X_SERIAL *src)
+{
+	X_SERIAL *s;
+	// 引数チェック
+	if (src == NULL)
+	{
+		return NULL;
+	}
+
+	s = ZeroMalloc(sizeof(X_SERIAL));
+	s->data = ZeroMalloc(src->size);
+	Copy(s->data, src->data, src->size);
+	s->size = src->size;
+
+	return s;
+}
+
+// X_SERIAL の初期化
+X_SERIAL *NewXSerial(void *data, UINT size)
+{
+	X_SERIAL *serial;
+	UCHAR *buf = (UCHAR *)data;
+	UINT i;
+	// 引数チェック
+	if (data == NULL || size == 0)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < size;i++)
+	{
+		if (buf[i] != 0)
+		{
+			break;
+		}
+	}
+	if (i == size)
+	{
+		i = size - 1;
+	}
+	buf += i;
+
+	serial = Malloc(sizeof(X_SERIAL));
+	serial->size = size - i;
+	serial->data = ZeroMalloc(size + 16);
+	Copy(serial->data, buf, size - i);
+
+	return serial;
+}
+
+// 2038 年 1 月 1 日までの日数を取得する
+UINT GetDaysUntil2038()
+{
+	UINT64 now = SystemTime64();
+	UINT64 target;
+	SYSTEMTIME st;
+
+	Zero(&st, sizeof(st));
+	st.wYear = 2038;
+	st.wMonth = 1;
+	st.wDay = 1;
+
+	target = SystemToUINT64(&st);
+
+	if (now >= target)
+	{
+		return 0;
+	}
+	else
+	{
+		return (UINT)((target - now) / (UINT64)(1000 * 60 * 60 * 24));
+	}
+}
+
+// X509 証明書を発行する
+X *NewX(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial)
+{
+	X509 *x509;
+	X *x;
+	// 引数チェック
+	if (pub == NULL || priv == NULL || name == NULL || ca == NULL)
+	{
+		return NULL;
+	}
+
+	x509 = NewX509(pub, priv, ca, name, days, serial);
+	if (x509 == NULL)
+	{
+		return NULL;
+	}
+
+	x = X509ToX(x509);
+
+	if (x == NULL)
+	{
+		return NULL;
+	}
+
+	return x;
+}
+
+// ルート証明書を作成する
+X *NewRootX(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial)
+{
+	X509 *x509;
+	X *x, *x2;
+	// 引数チェック
+	if (pub == NULL || priv == NULL || name == NULL)
+	{
+		return NULL;
+	}
+
+	x509 = NewRootX509(pub, priv, name, days, serial);
+	if (x509 == NULL)
+	{
+		return NULL;
+	}
+
+	x = X509ToX(x509);
+	if (x == NULL)
+	{
+		return NULL;
+	}
+
+	x2 = CloneX(x);
+	FreeX(x);
+
+	return x2;
+}
+
+// X509 証明書を発行する
+X509 *NewX509(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial)
+{
+	X509 *x509;
+	UINT64 notBefore, notAfter;
+	ASN1_TIME *t1, *t2;
+	X509_NAME *subject_name, *issuer_name;
+	// 引数チェック
+	if (pub == NULL || name == NULL || ca == NULL)
+	{
+		return NULL;
+	}
+	if (pub->private_key != false)
+	{
+		return NULL;
+	}
+	if (priv->private_key == false)
+	{
+		return NULL;
+	}
+
+	notBefore = SystemTime64();
+	notAfter = notBefore + (UINT64)days * (UINT64)3600 * (UINT64)24 * (UINT64)1000;
+
+
+	// X509 の作成
+	x509 = X509_new();
+	if (x509 == NULL)
+	{
+		return NULL;
+	}
+
+	// 有効期限の設定
+	t1 = X509_get_notBefore(x509);
+	t2 = X509_get_notAfter(x509);
+	if (!UINT64ToAsn1Time(t1, notBefore))
+	{
+		FreeX509(x509);
+		return NULL;
+	}
+	if (!UINT64ToAsn1Time(t2, notAfter))
+	{
+		FreeX509(x509);
+		return NULL;
+	}
+
+	// 名前の設定
+	subject_name = NameToX509Name(name);
+	if (subject_name == NULL)
+	{
+		FreeX509(x509);
+		return NULL;
+	}
+	issuer_name = X509_get_subject_name(ca->x509);
+	if (issuer_name == NULL)
+	{
+		FreeX509Name(subject_name);
+		FreeX509(x509);
+		return NULL;
+	}
+
+	X509_set_issuer_name(x509, issuer_name);
+	X509_set_subject_name(x509, subject_name);
+
+	FreeX509Name(subject_name);
+
+	// シリアル番号の設定
+	if (serial == NULL)
+	{
+		char zero = 0;
+		ASN1_INTEGER *s = x509->cert_info->serialNumber;
+		OPENSSL_free(s->data);
+		s->data = OPENSSL_malloc(sizeof(char));
+		Copy(s->data, &zero, sizeof(char));
+		s->length = sizeof(char);
+	}
+	else
+	{
+		ASN1_INTEGER *s = x509->cert_info->serialNumber;
+		OPENSSL_free(s->data);
+		s->data = OPENSSL_malloc(serial->size);
+		Copy(s->data, serial->data, serial->size);
+		s->length = serial->size;
+	}
+
+	Lock(openssl_lock);
+	{
+		// 公開鍵の設定
+		X509_set_pubkey(x509, pub->pkey);
+
+		// 署名
+		X509_sign(x509, priv->pkey, EVP_sha1());
+	}
+	Unlock(openssl_lock);
+
+	return x509;
+}
+
+// ルート X509 証明書を作成する
+X509 *NewRootX509(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial)
+{
+	X509 *x509;
+	UINT64 notBefore, notAfter;
+	ASN1_TIME *t1, *t2;
+	X509_NAME *subject_name, *issuer_name;
+	// 引数チェック
+	if (pub == NULL || name == NULL || priv == NULL)
+	{
+		return NULL;
+	}
+	if (days == 0)
+	{
+		days = 365;
+	}
+	if (priv->private_key == false)
+	{
+		return NULL;
+	}
+	if (pub->private_key != false)
+	{
+		return NULL;
+	}
+
+	notBefore = SystemTime64();
+	notAfter = notBefore + (UINT64)days * (UINT64)3600 * (UINT64)24 * (UINT64)1000;
+
+	// X509 の作成
+	x509 = X509_new();
+	if (x509 == NULL)
+	{
+		return NULL;
+	}
+
+	// 有効期限の設定
+	t1 = X509_get_notBefore(x509);
+	t2 = X509_get_notAfter(x509);
+	if (!UINT64ToAsn1Time(t1, notBefore))
+	{
+		FreeX509(x509);
+		return NULL;
+	}
+	if (!UINT64ToAsn1Time(t2, notAfter))
+	{
+		FreeX509(x509);
+		return NULL;
+	}
+
+	// 名前の設定
+	subject_name = NameToX509Name(name);
+	if (subject_name == NULL)
+	{
+		FreeX509(x509);
+		return NULL;
+	}
+	issuer_name = NameToX509Name(name);
+	if (issuer_name == NULL)
+	{
+		FreeX509Name(subject_name);
+		FreeX509(x509);
+		return NULL;
+	}
+
+	X509_set_issuer_name(x509, issuer_name);
+	X509_set_subject_name(x509, subject_name);
+
+	FreeX509Name(subject_name);
+	FreeX509Name(issuer_name);
+
+	// シリアル番号の設定
+	if (serial == NULL)
+	{
+		char zero = 0;
+		ASN1_INTEGER *s = x509->cert_info->serialNumber;
+		OPENSSL_free(s->data);
+		s->data = OPENSSL_malloc(sizeof(char));
+		Copy(s->data, &zero, sizeof(char));
+		s->length = sizeof(char);
+	}
+	else
+	{
+		ASN1_INTEGER *s = x509->cert_info->serialNumber;
+		OPENSSL_free(s->data);
+		s->data = OPENSSL_malloc(serial->size);
+		Copy(s->data, serial->data, serial->size);
+		s->length = serial->size;
+	}
+
+	Lock(openssl_lock);
+	{
+		// 公開鍵の設定
+		X509_set_pubkey(x509, pub->pkey);
+
+		// 署名
+		X509_sign(x509, priv->pkey, EVP_sha1());
+	}
+	Unlock(openssl_lock);
+
+	return x509;
+}
+
+// NAME を X509_NAME に変換
+void *NameToX509Name(NAME *nm)
+{
+	X509_NAME *xn;
+	// 引数チェック
+	if (nm == NULL)
+	{
+		return NULL;
+	}
+
+	xn = X509_NAME_new();
+	if (xn == NULL)
+	{
+		return NULL;
+	}
+
+	// エントリの追加
+	AddX509Name(xn, NID_commonName, nm->CommonName);
+	AddX509Name(xn, NID_organizationName, nm->Organization);
+	AddX509Name(xn, NID_organizationalUnitName, nm->Unit);
+	AddX509Name(xn, NID_countryName, nm->Country);
+	AddX509Name(xn, NID_stateOrProvinceName, nm->State);
+	AddX509Name(xn, NID_localityName, nm->Local);
+
+	return xn;
+}
+
+// X509_NAME にエントリを追加する
+bool AddX509Name(void *xn, int nid, wchar_t *str)
+{
+	X509_NAME *x509_name;
+	UINT utf8_size;
+	BYTE *utf8;
+	// 引数チェック
+	if (xn == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	// UTF-8 に変換
+	utf8_size = CalcUniToUtf8(str);
+	if (utf8_size == 0)
+	{
+		return false;
+	}
+	utf8 = ZeroMalloc(utf8_size + 1);
+	UniToUtf8(utf8, utf8_size, str);
+	utf8[utf8_size] = 0;
+
+	// 追加
+	x509_name = (X509_NAME *)xn;
+	Lock(openssl_lock);
+	{
+		X509_NAME_add_entry_by_NID(x509_name, nid, MBSTRING_ASC, utf8, utf8_size, -1, 0);
+	}
+	Unlock(openssl_lock);
+	Free(utf8);
+
+	return true;
+}
+
+// X509_NAME を解放
+void FreeX509Name(void *xn)
+{
+	X509_NAME *x509_name;
+	// 引数チェック
+	if (xn == NULL)
+	{
+		return;
+	}
+
+	x509_name = (X509_NAME *)xn;
+	X509_NAME_free(x509_name);
+}
+
+// NAME の作成
+NAME *NewName(wchar_t *common_name, wchar_t *organization, wchar_t *unit,
+			  wchar_t *country, wchar_t *state, wchar_t *local)
+{
+	NAME *nm = ZeroMalloc(sizeof(NAME));
+
+	if (UniIsEmptyStr(common_name) == false)
+	{
+		nm->CommonName = CopyUniStr(common_name);
+	}
+
+	if (UniIsEmptyStr(organization) == false)
+	{
+		nm->Organization = CopyUniStr(organization);
+	}
+
+	if (UniIsEmptyStr(unit) == false)
+	{
+		nm->Unit = CopyUniStr(unit);
+	}
+
+	if (UniIsEmptyStr(country) == false)
+	{
+		nm->Country = CopyUniStr(country);
+	}
+
+	if (UniIsEmptyStr(state) == false)
+	{
+		nm->State = CopyUniStr(state);
+	}
+
+	if (UniIsEmptyStr(local) == false)
+	{
+		nm->Local = CopyUniStr(local);
+	}
+
+	return nm;
+}
+
+// 証明書の有効期限を現在時刻で確認する
+bool CheckXDateNow(X *x)
+{
+	// 引数チェック
+	if (x == NULL)
+	{
+		return false;
+	}
+
+	return CheckXDate(x, SystemTime64());
+}
+
+// 証明書の有効期限を確認する
+bool CheckXDate(X *x, UINT64 current_system_time)
+{
+	// 引数チェック
+	if (x == NULL)
+	{
+		return false;
+	}
+
+	if (x->notBefore >= current_system_time || x->notAfter <= current_system_time)
+	{
+		return false;
+	}
+	return true;
+}
+
+// 証明書の有効期限情報を読み込む
+void LoadXDates(X *x)
+{
+	// 引数チェック
+	if (x == NULL)
+	{
+		return;
+	}
+
+	x->notBefore = Asn1TimeToUINT64(x->x509->cert_info->validity->notBefore);
+	x->notAfter = Asn1TimeToUINT64(x->x509->cert_info->validity->notAfter);
+}
+
+// 64bit システム時刻を ASN1 時刻に変換する
+bool UINT64ToAsn1Time(void *asn1_time, UINT64 t)
+{
+	SYSTEMTIME st;
+	// 引数チェック
+	if (asn1_time == NULL)
+	{
+		return false;
+	}
+
+	UINT64ToSystem(&st, t);
+	return SystemToAsn1Time(asn1_time, &st);
+}
+
+// システム時刻を ASN1 時刻に変換する
+bool SystemToAsn1Time(void *asn1_time, SYSTEMTIME *s)
+{
+	char tmp[20];
+	ASN1_TIME *t;
+	// 引数チェック
+	if (asn1_time == NULL || s == NULL)
+	{
+		return false;
+	}
+
+	if (SystemToStr(tmp, sizeof(tmp), s) == false)
+	{
+		return false;
+	}
+	t = (ASN1_TIME *)asn1_time;
+	if (t->data == NULL || t->length < sizeof(tmp))
+	{
+		t->data = OPENSSL_malloc(sizeof(tmp));
+	}
+	StrCpy((char *)t->data, t->length, tmp);
+	t->length = StrLen(tmp);
+	t->type = V_ASN1_UTCTIME;
+
+	return true;
+}
+
+// システム時刻を文字列に変換する
+bool SystemToStr(char *str, UINT size, SYSTEMTIME *s)
+{
+	// 引数チェック
+	if (str == NULL || s == NULL)
+	{
+		return false;
+	}
+
+	Format(str, size, "%02u%02u%02u%02u%02u%02uZ",
+		s->wYear % 100, s->wMonth, s->wDay,
+		s->wHour, s->wMinute, s->wSecond);
+
+	return true;
+}
+
+// ASN1 時刻を UINT64 時刻に変換する
+UINT64 Asn1TimeToUINT64(void *asn1_time)
+{
+	SYSTEMTIME st;
+	// 引数チェック
+	if (asn1_time == NULL)
+	{
+		return 0;
+	}
+
+	if (Asn1TimeToSystem(&st, asn1_time) == false)
+	{
+		return 0;
+	}
+	return SystemToUINT64(&st);
+}
+
+// ASN1 時刻をシステム時刻に変換する
+bool Asn1TimeToSystem(SYSTEMTIME *s, void *asn1_time)
+{
+	ASN1_TIME *t;
+	// 引数チェック
+	if (s == NULL || asn1_time == NULL)
+	{
+		return false;
+	}
+
+	t = (ASN1_TIME *)asn1_time;
+	if (StrToSystem(s, (char *)t->data) == false)
+	{
+		return false;
+	}
+
+	if (t->type == V_ASN1_GENERALIZEDTIME)
+	{
+		LocalToSystem(s, s);
+	}
+
+	return true;
+}
+
+// 文字列をシステム時刻に変換する
+bool StrToSystem(SYSTEMTIME *s, char *str)
+{
+	// 引数チェック
+	if (s == NULL || str == NULL)
+	{
+		return false;
+	}
+	if (StrLen(str) != 13)
+	{
+		return false;
+	}
+	if (str[12] != 'Z')
+	{
+		return false;
+	}
+
+	// 変換
+	{
+		char year[3] = {str[0], str[1], 0},
+			month[3] = {str[2], str[3], 0},
+			day[3] = {str[4], str[5], 0},
+			hour[3] = {str[6], str[7], 0},
+			minute[3] = {str[8], str[9], 0},
+			second[3] = {str[10], str[11], 0};
+		Zero(s, sizeof(SYSTEMTIME));
+		s->wYear = ToInt(year);
+		if (s->wYear >= 60)
+		{
+			s->wYear += 1900;
+		}
+		else
+		{
+			s->wYear += 2000;
+		}
+		s->wMonth = ToInt(month);
+		s->wDay = ToInt(day);
+		s->wHour = ToInt(hour);
+		s->wMinute = ToInt(minute);
+		s->wSecond = ToInt(second);
+		NormalizeSystem(s);
+	}
+
+	return true;
+}
+
+// RSA 署名の検査
+bool RsaVerify(void *data, UINT data_size, void *sign, K *k)
+{
+	return RsaVerifyEx(data, data_size, sign, k, 0);
+}
+bool RsaVerifyEx(void *data, UINT data_size, void *sign, K *k, UINT bits)
+{
+	UCHAR hash_data[SIGN_HASH_SIZE];
+	UCHAR decrypt_data[SIGN_HASH_SIZE];
+	// 引数チェック
+	if (data == NULL || sign == NULL || k == NULL || k->private_key != false)
+	{
+		return false;
+	}
+	if (bits == 0)
+	{
+		bits = 1024;
+	}
+
+	// データをハッシュ
+	if (HashForSign(hash_data, sizeof(hash_data), data, data_size) == false)
+	{
+		return false;
+	}
+
+	// 署名を解読
+	if (RSA_public_decrypt(bits / 8, sign, decrypt_data, k->pkey->pkey.rsa, RSA_PKCS1_PADDING) <= 0)
+	{
+		return false;
+	}
+
+	// 比較
+	if (Cmp(decrypt_data, hash_data, sizeof(SIGN_HASH_SIZE)) != 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// RSA 署名
+bool RsaSign(void *dst, void *src, UINT size, K *k)
+{
+	return RsaSignEx(dst, src, size, k, 0);
+}
+bool RsaSignEx(void *dst, void *src, UINT size, K *k, UINT bits)
+{
+	UCHAR hash[SIGN_HASH_SIZE];
+	// 引数チェック
+	if (dst == NULL || src == NULL || k == NULL || k->pkey->type != EVP_PKEY_RSA)
+	{
+		return false;
+	}
+	if (bits == 0)
+	{
+		bits = 1024;
+	}
+
+	Zero(dst, bits / 8);
+
+	// ハッシュ
+	if (HashForSign(hash, sizeof(hash), src, size) == false)
+	{
+		return false;
+	}
+
+	// 署名
+	if (RSA_private_encrypt(sizeof(hash), hash, dst, k->pkey->pkey.rsa, RSA_PKCS1_PADDING) <= 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// SHA-1 による署名データの生成
+bool HashForSign(void *dst, UINT dst_size, void *src, UINT src_size)
+{
+	UCHAR *buf = (UCHAR *)dst;
+	UCHAR sign_data[] =
+	{
+		0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
+		0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14,
+	};
+	// 引数チェック
+	if (dst == NULL || src == NULL || src_size == 0 || MIN_SIGN_HASH_SIZE > dst_size)
+	{
+		return false;
+	}
+
+	// ヘッダ部分
+	Copy(buf, sign_data, sizeof(sign_data));
+
+	// ハッシュ
+	HashSha1(HASHED_DATA(buf), src, src_size);
+
+	return true;
+}
+
+// RSA 公開鍵による復号化
+bool RsaPublicDecrypt(void *dst, void *src, UINT size, K *k)
+{
+	void *tmp;
+	int ret;
+	// 引数チェック
+	if (src == NULL || size == 0 || k == NULL)
+	{
+		return false;
+	}
+
+	tmp = ZeroMalloc(size);
+	Lock(openssl_lock);
+	{
+		ret = RSA_public_decrypt(size, src, tmp, k->pkey->pkey.rsa, RSA_NO_PADDING);
+	}
+	Unlock(openssl_lock);
+	if (ret <= 0)
+	{
+/*		Debug("RSA Error: 0x%x\n",
+			ERR_get_error());
+*/		Free(tmp);
+		return false;
+	}
+
+	Copy(dst, tmp, size);
+	Free(tmp);
+
+	return true;
+}
+
+// RSA 秘密鍵による暗号化
+bool RsaPrivateEncrypt(void *dst, void *src, UINT size, K *k)
+{
+	void *tmp;
+	int ret;
+	// 引数チェック
+	if (src == NULL || size == 0 || k == NULL)
+	{
+		return false;
+	}
+
+	tmp = ZeroMalloc(size);
+	Lock(openssl_lock);
+	{
+		ret = RSA_private_encrypt(size, src, tmp, k->pkey->pkey.rsa, RSA_NO_PADDING);
+	}
+	Unlock(openssl_lock);
+	if (ret <= 0)
+	{
+/*		Debug("RSA Error: %u\n",
+			ERR_GET_REASON(ERR_get_error()));
+*/		Free(tmp);
+		return false;
+	}
+
+	Copy(dst, tmp, size);
+	Free(tmp);
+
+	return true;
+}
+
+// RSA 秘密鍵による復号化
+bool RsaPrivateDecrypt(void *dst, void *src, UINT size, K *k)
+{
+	void *tmp;
+	int ret;
+	// 引数チェック
+	if (src == NULL || size == 0 || k == NULL)
+	{
+		return false;
+	}
+
+	tmp = ZeroMalloc(size);
+	Lock(openssl_lock);
+	{
+		ret = RSA_private_decrypt(size, src, tmp, k->pkey->pkey.rsa, RSA_NO_PADDING);
+	}
+	Unlock(openssl_lock);
+	if (ret <= 0)
+	{
+		return false;
+	}
+
+	Copy(dst, tmp, size);
+	Free(tmp);
+
+	return true;
+}
+
+// RSA 公開鍵による暗号化
+bool RsaPublicEncrypt(void *dst, void *src, UINT size, K *k)
+{
+	void *tmp;
+	int ret;
+	// 引数チェック
+	if (src == NULL || size == 0 || k == NULL)
+	{
+		return false;
+	}
+
+	tmp = ZeroMalloc(size);
+	Lock(openssl_lock);
+	{
+		ret = RSA_public_encrypt(size, src, tmp, k->pkey->pkey.rsa, RSA_NO_PADDING);
+	}
+	Unlock(openssl_lock);
+	if (ret <= 0)
+	{
+		return false;
+	}
+
+	Copy(dst, tmp, size);
+	Free(tmp);
+
+	return true;
+}
+
+// RSA 動作環境チェック
+bool RsaCheckEx()
+{
+	UINT num = 20;
+	UINT i;
+
+	for (i = 0;i < num;i++)
+	{
+		if (RsaCheck())
+		{
+			return true;
+		}
+
+		SleepThread(100);
+	}
+
+	return false;
+}
+bool RsaCheck()
+{
+	RSA *rsa;
+	K *priv_key, *pub_key;
+	BIO *bio;
+	char errbuf[MAX_SIZE];
+	UINT size = 0;
+	UINT bit = 32;
+	// 引数チェック
+
+	// 鍵生成
+	Lock(openssl_lock);
+	{
+		rsa = RSA_generate_key(bit, RSA_F4, NULL, NULL);
+	}
+	Unlock(openssl_lock);
+	if (rsa == NULL)
+	{
+		Debug("RSA_generate_key: err=%s\n", ERR_error_string(ERR_get_error(), errbuf));
+		return false;
+	}
+
+	// 秘密鍵
+	bio = NewBio();
+	Lock(openssl_lock);
+	{
+		i2d_RSAPrivateKey_bio(bio, rsa);
+	}
+	Unlock(openssl_lock);
+	BIO_seek(bio, 0);
+	priv_key = BioToK(bio, true, false, NULL);
+	FreeBio(bio);
+
+	// 公開鍵
+	bio = NewBio();
+	Lock(openssl_lock);
+	{
+		i2d_RSA_PUBKEY_bio(bio, rsa);
+	}
+	Unlock(openssl_lock);
+	BIO_seek(bio, 0);
+	pub_key = BioToK(bio, false, false, NULL);
+	FreeBio(bio);
+
+	RSA_free(rsa);
+
+	size = RsaPublicSize(pub_key);
+
+	if (size != ((bit + 7) / 8))
+	{
+		FreeK(priv_key);
+		FreeK(pub_key);
+
+		return false;
+	}
+
+	FreeK(priv_key);
+	FreeK(pub_key);
+
+	return true;
+}
+
+// RSA 鍵の生成
+bool RsaGen(K **priv, K **pub, UINT bit)
+{
+	RSA *rsa;
+	K *priv_key, *pub_key;
+	BIO *bio;
+	char errbuf[MAX_SIZE];
+	UINT size = 0;
+	// 引数チェック
+	if (priv == NULL || pub == NULL)
+	{
+		return false;
+	}
+	if (bit == 0)
+	{
+		bit = 1024;
+	}
+
+	// 鍵生成
+	Lock(openssl_lock);
+	{
+		rsa = RSA_generate_key(bit, RSA_F4, NULL, NULL);
+	}
+	Unlock(openssl_lock);
+	if (rsa == NULL)
+	{
+		Debug("RSA_generate_key: err=%s\n", ERR_error_string(ERR_get_error(), errbuf));
+		return false;
+	}
+
+	// 秘密鍵
+	bio = NewBio();
+	Lock(openssl_lock);
+	{
+		i2d_RSAPrivateKey_bio(bio, rsa);
+	}
+	Unlock(openssl_lock);
+	BIO_seek(bio, 0);
+	priv_key = BioToK(bio, true, false, NULL);
+	FreeBio(bio);
+
+	// 公開鍵
+	bio = NewBio();
+	Lock(openssl_lock);
+	{
+		i2d_RSA_PUBKEY_bio(bio, rsa);
+	}
+	Unlock(openssl_lock);
+	BIO_seek(bio, 0);
+	pub_key = BioToK(bio, false, false, NULL);
+	FreeBio(bio);
+
+	*priv = priv_key;
+	*pub = pub_key;
+
+	RSA_free(rsa);
+
+	size = RsaPublicSize(*pub);
+
+	if (size != ((bit + 7) / 8))
+	{
+		FreeK(*priv);
+		FreeK(*pub);
+
+		return RsaGen(priv, pub, bit);
+	}
+
+	return true;
+}
+
+// 証明書 X が証明書 x_issuer の発行者によって署名されているかどうか確認する
+bool CheckX(X *x, X *x_issuer)
+{
+	K *k;
+	bool ret;
+	// 引数チェック
+	if (x == NULL || x_issuer == NULL)
+	{
+		return false;
+	}
+
+	k = GetKFromX(x_issuer);
+	if (k == NULL)
+	{
+		return false;
+	}
+
+	ret = CheckSignature(x, k);
+	FreeK(k);
+
+	return ret;
+}
+
+// 証明書 X の署名を公開鍵 K で確認する
+bool CheckSignature(X *x, K *k)
+{
+	// 引数チェック
+	if (x == NULL || k == NULL)
+	{
+		return false;
+	}
+
+	Lock(openssl_lock);
+	{
+		if (X509_verify(x->x509, k->pkey) == 0)
+		{
+			Unlock(openssl_lock);
+			return false;
+		}
+	}
+	Unlock(openssl_lock);
+	return true;
+}
+
+// 証明書から公開鍵を取得する
+K *GetKFromX(X *x)
+{
+	EVP_PKEY *pkey;
+	K *k;
+	// 引数チェック
+	if (x == NULL)
+	{
+		return NULL;
+	}
+
+	Lock(openssl_lock);
+	{
+		pkey = X509_get_pubkey(x->x509);
+	}
+	Unlock(openssl_lock);
+	if (pkey == NULL)
+	{
+		return NULL;
+	}
+
+	k = ZeroMalloc(sizeof(K));
+	k->pkey = pkey;
+
+	return k;
+}
+
+// 名前の比較
+bool CompareName(NAME *n1, NAME *n2)
+{
+	// 引数チェック
+	if (n1 == NULL || n2 == NULL)
+	{
+		return false;
+	}
+
+	// 名前比較
+	if (UniStrCmpi(n1->CommonName, n2->CommonName) == 0 &&
+		UniStrCmpi(n1->Organization, n2->Organization) == 0 &&
+		UniStrCmpi(n1->Unit, n2->Unit) == 0 &&
+		UniStrCmpi(n1->Country, n2->Country) == 0 &&
+		UniStrCmpi(n1->State, n2->State) == 0 &&
+		UniStrCmpi(n1->Local, n2->Local) == 0)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// X の名前の解放
+void FreeXNames(X *x)
+{
+	// 引数チェック
+	if (x == NULL)
+	{
+		return;
+	}
+
+	FreeName(x->issuer_name);
+	x->issuer_name = NULL;
+
+	FreeName(x->subject_name);
+	x->subject_name = NULL;
+}
+
+// 名前の解放
+void FreeName(NAME *n)
+{
+	// 引数チェック
+	if (n == NULL)
+	{
+		return;
+	}
+
+	// 文字列を解放
+	Free(n->CommonName);
+	Free(n->Organization);
+	Free(n->Unit);
+	Free(n->Country);
+	Free(n->State);
+	Free(n->Local);
+
+	// オブジェクトを解放
+	Free(n);
+
+	return;
+}
+
+// 証明書の名前を取得する
+void LoadXNames(X *x)
+{
+	X509 *x509;
+	// 引数チェック
+	if (x == NULL)
+	{
+		return;
+	}
+
+	x509 = x->x509;
+	x->issuer_name = X509NameToName(X509_get_issuer_name(x509));
+	x->subject_name = X509NameToName(X509_get_subject_name(x509));
+}
+
+// X509_NAME 構造体を NAME 構造体に変換
+NAME *X509NameToName(void *xn)
+{
+	NAME *n;
+	// 引数チェック
+	if (xn == NULL)
+	{
+		return NULL;
+	}
+
+	n = ZeroMalloc(sizeof(NAME));
+
+	// 文字列を順番に取得する
+	n->CommonName = GetUniStrFromX509Name(xn, NID_commonName);
+	n->Organization = GetUniStrFromX509Name(xn, NID_organizationName);
+	n->Unit = GetUniStrFromX509Name(xn, NID_organizationalUnitName);
+	n->Country = GetUniStrFromX509Name(xn, NID_countryName);
+	n->State = GetUniStrFromX509Name(xn, NID_stateOrProvinceName);
+	n->Local = GetUniStrFromX509Name(xn, NID_localityName);
+
+	return n;
+}
+
+// X509_NAME 構造体の中から Unicode 文字列を読み込む
+wchar_t *GetUniStrFromX509Name(void *xn, int nid)
+{
+	UCHAR txt[1024];
+	bool b = false;
+	UINT i, size;
+	int index;
+	bool unicode = false;
+	bool is_utf_8 = false;
+	ASN1_OBJECT *obj;
+	ASN1_STRING *data;
+	// 引数チェック
+	if (xn == NULL || nid == 0)
+	{
+		return NULL;
+	}
+
+	Zero(txt, sizeof(txt));
+	if (X509_NAME_get_text_by_NID(xn, nid, (char *)txt, sizeof(txt) - 2) <= 0)
+	{
+		return NULL;
+	}
+
+	obj = OBJ_nid2obj(nid);
+	if (obj == NULL)
+	{
+		return NULL;
+	}
+	index = X509_NAME_get_index_by_OBJ(xn, obj, -1);
+	if (index < 0)
+	{
+		return NULL;
+	}
+	data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(xn, index));
+	if (data == NULL)
+	{
+		return NULL;
+	}
+	if (data->type == V_ASN1_BMPSTRING)
+	{
+		unicode = true;
+	}
+	if (data->type == V_ASN1_UTF8STRING || data->type == V_ASN1_T61STRING)
+	{
+		is_utf_8 = true;
+	}
+
+	size = UniStrLen((wchar_t *)txt) * 4 + 8;
+	for (i = 0;i < size;i++)
+	{
+		if (txt[i] >= 0x80)
+		{
+			unicode = true;
+			break;
+		}
+	}
+
+	if (is_utf_8)
+	{
+		wchar_t *ret;
+		UINT ret_size;
+
+		ret_size = CalcUtf8ToUni(txt, StrLen(txt));
+		ret = ZeroMalloc(ret_size + 8);
+		Utf8ToUni(ret, ret_size, txt, StrLen(txt));
+
+		return ret;
+	}
+	else if (unicode == false)
+	{
+		wchar_t tmp[1024];
+		StrToUni(tmp, sizeof(tmp), (char *)txt);
+		return CopyUniStr(tmp);
+	}
+	else
+	{
+		EndianUnicode((wchar_t *)txt);
+		return CopyUniStr((wchar_t *)txt);
+	}
+}
+
+// 証明書 x1 と x2 が等しいかどうかチェックする
+bool CompareX(X *x1, X *x2)
+{
+	// 引数チェック
+	if (x1 == NULL || x2 == NULL)
+	{
+		return false;
+	}
+
+	Lock(openssl_lock);
+	if (X509_cmp(x1->x509, x2->x509) == 0)
+	{
+		Unlock(openssl_lock);
+		return true;
+	}
+	else
+	{
+		Unlock(openssl_lock);
+		return false;
+	}
+}
+
+// K が X の秘密鍵かどうかチェックする
+bool CheckXandK(X *x, K *k)
+{
+	// 引数チェック
+	if (x == NULL || k == NULL)
+	{
+		return false;
+	}
+
+	Lock(openssl_lock);
+	if (X509_check_private_key(x->x509, k->pkey) != 0)
+	{
+		Unlock(openssl_lock);
+		return true;
+	}
+	else
+	{
+		Unlock(openssl_lock);
+		return false;
+	}
+}
+
+// ファイルから X を読み込む
+X *FileToX(char *filename)
+{
+	wchar_t *filename_w = CopyStrToUni(filename);
+	X *ret = FileToXW(filename_w);
+
+	Free(filename_w);
+
+	return ret;
+}
+X *FileToXW(wchar_t *filename)
+{
+	bool text;
+	BUF *b;
+	X *x;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return NULL;
+	}
+
+	b = ReadDumpW(filename);
+	text = IsBase64(b);
+
+	x = BufToX(b, text);
+	FreeBuf(b);
+
+	return x;
+}
+
+// X をファイルに書き出す
+bool XToFile(X *x, char *filename, bool text)
+{
+	wchar_t *filename_w = CopyStrToUni(filename);
+	bool ret = XToFileW(x, filename_w, text);
+
+	Free(filename_w);
+
+	return ret;
+}
+bool XToFileW(X *x, wchar_t *filename, bool text)
+{
+	BUF *b;
+	bool ret;
+	// 引数チェック
+	if (x == NULL || filename == NULL)
+	{
+		return false;
+	}
+
+	b = XToBuf(x, text);
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	ret = DumpBufW(b, filename);
+	FreeBuf(b);
+
+	return ret;
+}
+
+// ファイルから K を読み込む
+K *FileToK(char *filename, bool private_key, char *password)
+{
+	wchar_t *filename_w = CopyStrToUni(filename);
+	K *ret;
+
+	ret = FileToKW(filename_w, private_key, password);
+
+	Free(filename_w);
+
+	return ret;
+}
+K *FileToKW(wchar_t *filename, bool private_key, char *password)
+{
+	bool text;
+	BUF *b;
+	K *k;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return NULL;
+	}
+
+	b = ReadDumpW(filename);
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	text = IsBase64(b);
+	if (text == false)
+	{
+		k = BufToK(b, private_key, false, NULL);
+	}
+	else
+	{
+		k = BufToK(b, private_key, true, NULL);
+		if (k == NULL)
+		{
+			k = BufToK(b, private_key, true, password);
+		}
+	}
+
+	FreeBuf(b);
+
+	return k;
+}
+
+// K をファイルに保存する
+bool KToFile(K *k, char *filename, bool text, char *password)
+{
+	wchar_t *filename_w = CopyStrToUni(filename);
+	bool ret = KToFileW(k, filename_w, text, password);
+
+	Free(filename_w);
+
+	return ret;
+}
+bool KToFileW(K *k, wchar_t *filename, bool text, char *password)
+{
+	BUF *b;
+	bool ret;
+	// 引数チェック
+	if (k == NULL || filename == NULL)
+	{
+		return false;
+	}
+
+	b = KToBuf(k, text, password);
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	ret = DumpBufW(b, filename);
+	FreeBuf(b);
+
+	return ret;
+}
+
+// K を BUF に変換する
+BUF *KToBuf(K *k, bool text, char *password)
+{
+	BUF *buf;
+	BIO *bio;
+	// 引数チェック
+	if (k == NULL)
+	{
+		return NULL;
+	}
+
+	bio = KToBio(k, text, password);
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	buf = BioToBuf(bio);
+	FreeBio(bio);
+
+	SeekBuf(buf, 0, 0);
+
+	return buf;
+}
+
+// K を BIO に変換する
+BIO *KToBio(K *k, bool text, char *password)
+{
+	BIO *bio;
+	// 引数チェック
+	if (k == NULL)
+	{
+		return NULL;
+	}
+
+	bio = NewBio();
+
+	if (k->private_key)
+	{
+		// 秘密鍵
+		if (text == false)
+		{
+			// バイナリ形式
+			Lock(openssl_lock);
+			{
+				i2d_PrivateKey_bio(bio, k->pkey);
+			}
+			Unlock(openssl_lock);
+		}
+		else
+		{
+			// テキスト形式
+			if (password == 0 || StrLen(password) == 0)
+			{
+				// 暗号化無し
+				Lock(openssl_lock);
+				{
+					PEM_write_bio_PrivateKey(bio, k->pkey, NULL, NULL, 0, NULL, NULL);
+				}
+				Unlock(openssl_lock);
+			}
+			else
+			{
+				// 暗号化する
+				CB_PARAM cb;
+				cb.password = password;
+				Lock(openssl_lock);
+				{
+					PEM_write_bio_PrivateKey(bio, k->pkey, EVP_des_ede3_cbc(),
+						NULL, 0, (pem_password_cb *)PKeyPasswordCallbackFunction, &cb);
+				}
+				Unlock(openssl_lock);
+			}
+		}
+	}
+	else
+	{
+		// 公開鍵
+		if (text == false)
+		{
+			// バイナリ形式
+			Lock(openssl_lock);
+			{
+				i2d_PUBKEY_bio(bio, k->pkey);
+			}
+			Unlock(openssl_lock);
+		}
+		else
+		{
+			// テキスト形式
+			Lock(openssl_lock);
+			{
+				PEM_write_bio_PUBKEY(bio, k->pkey);
+			}
+			Unlock(openssl_lock);
+		}
+	}
+
+	return bio;
+}
+
+// BUF が Base64 エンコードされているかどうか調べる
+bool IsBase64(BUF *b)
+{
+	UINT i;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;i < b->Size;i++)
+	{
+		char c = ((char *)b->Buf)[i];
+		bool b = false;
+		if ('a' <= c && c <= 'z')
+		{
+			b = true;
+		}
+		else if ('A' <= c && c <= 'Z')
+		{
+			b = true;
+		}
+		else if ('0' <= c && c <= '9')
+		{
+			b = true;
+		}
+		else if (c == ':' || c == '.' || c == ';' || c == ',')
+		{
+			b = true;
+		}
+		else if (c == '!' || c == '&' || c == '#' || c == '(' || c == ')')
+		{
+			b = true;
+		}
+		else if (c == '-' || c == ' ')
+		{
+			b = true;
+		}
+		else if (c == 13 || c == 10 || c == EOF)
+		{
+			b = true;
+		}
+		else if (c == '\t' || c == '=' || c == '+' || c == '/')
+		{
+			b = true;
+		}
+		if (b == false)
+		{
+			return false;
+		}
+	}
+	return true;
+}
+
+// BUF に含まれている K が暗号化されているかどうか調べる
+bool IsEncryptedK(BUF *b, bool private_key)
+{
+	K *k;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return false;
+	}
+	if (IsBase64(b) == false)
+	{
+		return false;
+	}
+
+	k = BufToK(b, private_key, true, NULL);
+	if (k != NULL)
+	{
+		FreeK(k);
+		return false;
+	}
+
+	return true;
+}
+
+// BUF を K に変換
+K *BufToK(BUF *b, bool private_key, bool text, char *password)
+{
+	BIO *bio;
+	K *k;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	bio = BufToBio(b);
+	k = BioToK(bio, private_key, text, password);
+	FreeBio(bio);
+
+	return k;
+}
+
+// K を解放
+void FreeK(K *k)
+{
+	// 引数チェック
+	if (k == NULL)
+	{
+		return;
+	}
+
+	FreePKey(k->pkey);
+	Free(k);
+}
+
+// 秘密鍵を解放
+void FreePKey(EVP_PKEY *pkey)
+{
+	// 引数チェック
+	if (pkey == NULL)
+	{
+		return;
+	}
+
+	EVP_PKEY_free(pkey);
+}
+
+// BIO を K に変換する
+K *BioToK(BIO *bio, bool private_key, bool text, char *password)
+{
+	EVP_PKEY *pkey;
+	K *k;
+	// 引数チェック
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	if (password != NULL && StrLen(password) == 0)
+	{
+		password = NULL;
+	}
+
+	if (private_key == false)
+	{
+		// 公開鍵
+		if (text == false)
+		{
+			// バイナリ形式
+			pkey = d2i_PUBKEY_bio(bio, NULL);
+			if (pkey == NULL)
+			{
+				return NULL;
+			}
+		}
+		else
+		{
+			// テキスト形式
+			CB_PARAM cb;
+			cb.password = password;
+			Lock(openssl_lock);
+			{
+				pkey = PEM_read_bio_PUBKEY(bio, NULL, (pem_password_cb *)PKeyPasswordCallbackFunction, &cb);
+			}
+			Unlock(openssl_lock);
+			if (pkey == NULL)
+			{
+				return NULL;
+			}
+		}
+	}
+	else
+	{
+		if (text == false)
+		{
+			// バイナリ形式
+			Lock(openssl_lock);
+			{
+				pkey = d2i_PrivateKey_bio(bio, NULL);
+			}
+			Unlock(openssl_lock);
+			if (pkey == NULL)
+			{
+				return NULL;
+			}
+		}
+		else
+		{
+			// テキスト形式
+			CB_PARAM cb;
+			cb.password = password;
+			Lock(openssl_lock);
+			{
+				pkey = PEM_read_bio_PrivateKey(bio, NULL, (pem_password_cb *)PKeyPasswordCallbackFunction, &cb);
+			}
+			Unlock(openssl_lock);
+			if (pkey == NULL)
+			{
+				return NULL;
+			}
+		}
+	}
+
+	k = ZeroMalloc(sizeof(K));
+	k->pkey = pkey;
+	k->private_key = private_key;
+
+	return k;
+}
+
+// パスワードコールバック関数
+int PKeyPasswordCallbackFunction(char *buf, int bufsize, int verify, void *param)
+{
+	CB_PARAM *cb;
+	// 引数チェック
+	if (buf == NULL || param == NULL || bufsize == 0)
+	{
+		return 0;
+	}
+
+	cb = (CB_PARAM *)param;
+	if (cb->password == NULL)
+	{
+		return 0;
+	}
+
+	return StrCpy(buf, bufsize, cb->password);
+}
+
+// X を BUF に変換する
+BUF *XToBuf(X *x, bool text)
+{
+	BIO *bio;
+	BUF *b;
+	// 引数チェック
+	if (x == NULL)
+	{
+		return NULL;
+	}
+
+	bio = XToBio(x, text);
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	b = BioToBuf(bio);
+	FreeBio(bio);
+
+	SeekBuf(b, 0, 0);
+
+	return b;
+}
+
+// X を BIO に変換する
+BIO *XToBio(X *x, bool text)
+{
+	BIO *bio;
+	// 引数チェック
+	if (x == NULL)
+	{
+		return NULL;
+	}
+
+	bio = NewBio();
+
+	Lock(openssl_lock);
+	{
+		if (text == false)
+		{
+			// バイナリ形式
+			i2d_X509_bio(bio, x->x509);
+		}
+		else
+		{
+			// テキスト形式
+			PEM_write_bio_X509(bio, x->x509);
+		}
+	}
+	Unlock(openssl_lock);
+
+	return bio;
+}
+
+// X の解放
+void FreeX(X *x)
+{
+	// 引数チェック
+	if (x == NULL)
+	{
+		return;
+	}
+
+	// 名前解放
+	FreeXNames(x);
+
+
+	// シリアル解放
+	FreeXSerial(x->serial);
+
+	if (x->do_not_free == false)
+	{
+		FreeX509(x->x509);
+	}
+	Free(x);
+}
+
+// X509 の解放
+void FreeX509(X509 *x509)
+{
+	// 引数チェック
+	if (x509 == NULL)
+	{
+		return;
+	}
+
+	Lock(openssl_lock);
+	{
+		X509_free(x509);
+	}
+	Unlock(openssl_lock);
+}
+
+// BUF を X に変換する
+X *BufToX(BUF *b, bool text)
+{
+	X *x;
+	BIO *bio;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	bio = BufToBio(b);
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	x = BioToX(bio, text);
+
+	FreeBio(bio);
+
+	return x;
+}
+
+// X のダイジェストを取得する
+void GetXDigest(X *x, UCHAR *buf, bool sha1)
+{
+	// 引数チェック
+	if (x == NULL)
+	{
+		return;
+	}
+
+	if (sha1 == false)
+	{
+		UINT size = MD5_SIZE;
+		X509_digest(x->x509, EVP_md5(), buf, (unsigned int *)&size);
+	}
+	else
+	{
+		UINT size = SHA1_SIZE;
+		X509_digest(x->x509, EVP_sha1(), buf, (unsigned int *)&size);
+	}
+}
+
+// BIO を X に変換する
+X *BioToX(BIO *bio, bool text)
+{
+	X *x;
+	X509 *x509;
+	// 引数チェック
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	Lock(openssl_lock);
+	{
+		// x509 の読み込み
+		if (text == false)
+		{
+			// バイナリモード
+			x509 = d2i_X509_bio(bio, NULL);
+		}
+		else
+		{
+			// テキストモード
+			x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+		}
+	}
+	Unlock(openssl_lock);
+
+	if (x509 == NULL)
+	{
+		return NULL;
+	}
+
+	x = X509ToX(x509);
+
+	if (x == NULL)
+	{
+		return NULL;
+	}
+
+	return x;
+}
+
+// X509 を X に変換する
+X *X509ToX(X509 *x509)
+{
+	X *x;
+	K *k;
+	BUF *b;
+	UINT size;
+	UINT type;
+	// 引数チェック
+	if (x509 == NULL)
+	{
+		return NULL;
+	}
+
+	x = ZeroMalloc(sizeof(X));
+	x->x509 = x509;
+
+	// 名前
+	LoadXNames(x);
+
+	// 有効期限
+	LoadXDates(x);
+
+	// ルート証明書かどうかチェックする
+	if (CompareName(x->issuer_name, x->subject_name))
+	{
+		K *pubkey = GetKFromX(x);
+		if (pubkey != NULL)
+		{
+			if (CheckXandK(x, pubkey))
+			{
+				x->root_cert = true;
+			}
+			FreeK(pubkey);
+		}
+	}
+
+	// シリアル番号の取得
+	x->serial = NewXSerial(x509->cert_info->serialNumber->data,
+		x509->cert_info->serialNumber->length);
+	if (x->serial == NULL)
+	{
+		char zero = 0;
+		x->serial = NewXSerial(&zero, sizeof(char));
+	}
+
+	k = GetKFromX(x);
+	if (k == NULL)
+	{
+		FreeX(x);
+		return NULL;
+	}
+
+	b = KToBuf(k, false, NULL);
+
+	size = b->Size;
+	type = k->pkey->type;
+
+	FreeBuf(b);
+
+	FreeK(k);
+
+	if (type == EVP_PKEY_RSA)
+	{
+		x->is_compatible_bit = true;
+
+		switch (size)
+		{
+		case 162:
+			x->bits = 1024;
+			break;
+
+		case 226:
+			x->bits = 1536;
+			break;
+
+		case 294:
+			x->bits = 2048;
+			break;
+
+		case 442:
+			x->bits = 3072;
+			break;
+
+		case 550:
+			x->bits = 4096;
+			break;
+
+		default:
+			x->is_compatible_bit = false;
+			break;
+		}
+	}
+
+	return x;
+}
+
+// BIO を作成する
+BIO *NewBio()
+{
+	return BIO_new(BIO_s_mem());
+}
+
+// BIO を解放する
+void FreeBio(BIO *bio)
+{
+	// 引数チェック
+	if (bio == NULL)
+	{
+		return;
+	}
+
+	BIO_free(bio);
+}
+
+// BIO を BUF に変換する
+BUF *BioToBuf(BIO *bio)
+{
+	BUF *b;
+	UINT size;
+	void *tmp;
+	// 引数チェック
+	if (bio == NULL)
+	{
+		return NULL;
+	}
+
+	BIO_seek(bio, 0);
+	size = bio->num_write;
+	tmp = Malloc(size);
+	BIO_read(bio, tmp, size);
+
+	b = NewBuf();
+	WriteBuf(b, tmp, size);
+	Free(tmp);
+
+	return b;
+}
+
+// BUF を BIO に変換する
+BIO *BufToBio(BUF *b)
+{
+	BIO *bio;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	Lock(openssl_lock);
+	{
+		bio = BIO_new(BIO_s_mem());
+		if (bio == NULL)
+		{
+			Unlock(openssl_lock);
+			return NULL;
+		}
+		BIO_write(bio, b->Buf, b->Size);
+		BIO_seek(bio, 0);
+	}
+	Unlock(openssl_lock);
+
+	return bio;
+}
+
+// 128bit 乱数生成
+void Rand128(void *buf)
+{
+	Rand(buf, 16);
+}
+
+// 64bit 乱数生成
+UINT64 Rand64()
+{
+	UINT64 i;
+	Rand(&i, sizeof(i));
+	return i;
+}
+
+// 32bit 乱数生成
+UINT Rand32()
+{
+	UINT i;
+	Rand(&i, sizeof(i));
+	return i;
+}
+
+// 16bit 乱数生成
+USHORT Rand16()
+{
+	USHORT i;
+	Rand(&i, sizeof(i));
+	return i;
+}
+
+// 8bit 乱数生成
+UCHAR Rand8()
+{
+	UCHAR i;
+	Rand(&i, sizeof(i));
+	return i;
+}
+
+// 1bit 乱数生成
+bool Rand1()
+{
+	return (Rand32() % 2) == 0 ? false : true;
+}
+
+// 乱数生成
+void Rand(void *buf, UINT size)
+{
+	// 引数チェック
+	if (buf == NULL || size == 0)
+	{
+		return;
+	}
+	RAND_bytes(buf, size);
+}
+
+// OpenSSL が確保しているスレッド固有情報を削除する
+void FreeOpenSSLThreadState()
+{
+	ERR_remove_state(0);
+}
+
+// 暗号化ライブラリの解放
+void FreeCryptLibrary()
+{
+	openssl_inited = false;
+
+	DeleteLock(openssl_lock);
+	openssl_lock = NULL;
+//	RAND_Free_For_SoftEther();
+	OpenSSL_FreeLock();
+}
+
+// 暗号化ライブラリの初期化
+void InitCryptLibrary()
+{
+	char tmp[16];
+//	RAND_Init_For_SoftEther()
+	openssl_lock = NewLock();
+	SSL_library_init();
+	//OpenSSL_add_all_algorithms();
+	OpenSSL_add_all_ciphers();
+	SSLeay_add_all_digests();
+	ERR_load_crypto_strings();
+	SSL_load_error_strings();
+
+#ifdef	OS_UNIX
+	{
+		char *name1 = "/dev/random";
+		char *name2 = "/dev/urandom";
+		IO *o;
+		o = FileOpen(name1, false);
+		if (o == NULL)
+		{
+			o = FileOpen(name2, false);
+			if (o == NULL)
+			{
+				UINT64 now = SystemTime64();
+				BUF *b;
+				UINT i;
+				b = NewBuf();
+				for (i = 0;i < 4096;i++)
+				{
+					UCHAR c = rand() % 256;
+					WriteBuf(b, &c, 1);
+				}
+				WriteBuf(b, &now, sizeof(now));
+				RAND_seed(b->Buf, b->Size);
+				FreeBuf(b);
+			}
+			else
+			{
+				FileClose(o);
+			}
+		}
+		else
+		{
+			FileClose(o);
+		}
+	}
+#endif	// OS_UNIX
+
+	RAND_poll();
+
+#ifdef	OS_WIN32
+//	RAND_screen();
+#endif
+	Rand(tmp, sizeof(tmp));
+	OpenSSL_InitLock();
+
+	openssl_inited = true;
+}
+
+// 内部ハッシュ関数
+void InternalHash(void *dst, void *src, UINT size, bool sha1)
+{
+	// 引数チェック
+	if (dst == NULL || (src == NULL && size != 0))
+	{
+		return;
+	}
+
+	if (sha1 == false)
+	{
+		// MD5 ハッシュ
+		MD5(src, size, dst);
+	}
+	else
+	{
+		// SHA ハッシュ
+		SHA(src, size, dst);
+	}
+}
+
+// SHA-1 専用ハッシュ関数
+void HashSha1(void *dst, void *src, UINT size)
+{
+	SHA1(src, size, dst);
+}
+
+// ハッシュ関数
+void Hash(void *dst, void *src, UINT size, bool sha1)
+{
+	InternalHash(dst, src, size, sha1);
+}
+
+// 新しい CRYPT オブジェクトの作成
+CRYPT *NewCrypt(void *key, UINT size)
+{
+	CRYPT *c = ZeroMalloc(sizeof(CRYPT));
+
+	SetKey(c, key, size);
+
+	return c;
+}
+
+// CRYPT オブジェクトの解放
+void FreeCrypt(CRYPT *c)
+{
+	// 引数チェック
+	if (c == NULL)
+	{
+		return;
+	}
+
+	// メモリ解放
+	Free(c);
+}
+
+// 暗号化と解読
+void InternalEncrypt(CRYPT *c, void *dst, void *src, UINT size)
+{
+	UINT x, y, sx, sy;
+	UINT *state;
+	UCHAR *endsrc;
+	UCHAR *s = (UCHAR *)src;
+	UCHAR *d = (UCHAR *)dst;
+	// 引数チェック
+	if (c == NULL || dst == NULL || src == NULL || size == 0)
+	{
+		return;
+	}
+
+	state = (UINT *)c->state;
+	x = c->x;
+	y = c->y;
+
+	for (endsrc = s + size;s != endsrc;s++, d++)
+	{
+		x = (x + 1) & 0xff;
+		sx = state[x];
+		y = (sx + y) & 0xff;
+		state[x] = sy = state[y];
+		state[y] = sx;
+		*d = *s ^ state[(sx + sy) & 0xff];
+	}
+	c->x = x;
+	c->y = y;
+}
+void Encrypt(CRYPT *c, void *dst, void *src, UINT size)
+{
+	InternalEncrypt(c, dst, src, size);
+}
+
+// 鍵の更新
+void SetKey(CRYPT *c, void *key, UINT size)
+{
+	UINT i, t, u, ki, si;
+	UINT *state;
+	UCHAR *k = (UCHAR *)key;
+	// 引数チェック
+	if (c == NULL || key == NULL)
+	{
+		return;
+	}
+
+	// 鍵のセット
+	state = (UINT *)c->state;
+	c->x = c->y = 0;
+	for (i = 0;i < 256;i++)
+	{
+		state[i] = i;
+	}
+	ki = si = 0;
+
+	for (i = 0;i < 256;i++)
+	{
+		t = state[i];
+		si = (si + k[ki] + t) & 0xff;
+		u = state[si];
+		state[si] = t;
+		state[i] = u;
+		if (++ki >= size)
+		{
+			ki = 0;
+		}
+	}
+}
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Encrypt.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Encrypt.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Encrypt.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,320 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Encrypt.h
+// Encrypt.c のヘッダ
+
+#ifndef	ENCRYPT_H
+#define	ENCRYPT_H
+
+// OpenSSL の関数
+void RAND_Init_For_SoftEther();
+void RAND_Free_For_SoftEther();
+
+
+
+// 定数
+#define	MIN_SIGN_HASH_SIZE		(15 + SHA1_SIZE)
+#define	SIGN_HASH_SIZE			(MIN_SIGN_HASH_SIZE)
+
+// マクロ
+#define	HASHED_DATA(p)			(((UCHAR *)p) + 15)
+
+
+
+// 暗号化コンテキスト
+struct CRYPT
+{
+	int x, y;
+	int state[256];
+};
+
+// 証明書内の名前
+struct NAME
+{
+	wchar_t *CommonName;		// CN
+	wchar_t *Organization;		// O
+	wchar_t *Unit;				// OU
+	wchar_t *Country;			// C
+	wchar_t *State;				// ST
+	wchar_t *Local;				// L
+};
+
+// シリアル番号
+struct X_SERIAL
+{
+	UINT size;
+	UCHAR *data;
+};
+
+// 証明書
+struct X
+{
+	X509 *x509;
+	NAME *issuer_name;
+	NAME *subject_name;
+	bool root_cert;
+	UINT64 notBefore;
+	UINT64 notAfter;
+	X_SERIAL *serial;
+	bool do_not_free;
+	bool is_compatible_bit;
+	UINT bits;
+};
+
+// 鍵
+struct K
+{
+	EVP_PKEY *pkey;
+	bool private_key;
+};
+
+// PKCS#12
+struct P12
+{
+	PKCS12 *pkcs12;
+};
+
+// CEL
+struct X_CRL
+{
+	X509_CRL *Crl;
+};
+
+// 定数
+#define	MD5_SIZE	16
+#define	SHA1_SIZE	20
+
+// OpenSSL のロック
+extern LOCK **ssl_lock_obj;
+
+// 関数プロトタイプ
+CRYPT *NewCrypt(void *key, UINT size);
+void FreeCrypt(CRYPT *c);
+void SetKey(CRYPT *c, void *key, UINT size);
+void Encrypt(CRYPT *c, void *dst, void *src, UINT size);
+void InternalEncrypt(CRYPT *c, void *dst, void *src, UINT size);
+void Hash(void *dst, void *src, UINT size, bool sha1);
+void HashSha1(void *dst, void *src, UINT size);
+void InternalHash(void *dst, void *src, UINT size, bool sha1);
+void InitCryptLibrary();
+void Rand(void *buf, UINT size);
+void Rand128(void *buf);
+UINT64 Rand64();
+UINT Rand32();
+USHORT Rand16();
+UCHAR Rand8();
+bool Rand1();
+UINT HashPtrToUINT(void *p);
+
+void CertTest();
+BIO *BufToBio(BUF *b);
+BUF *BioToBuf(BIO *bio);
+BIO *NewBio();
+void FreeBio(BIO *bio);
+X *BioToX(BIO *bio, bool text);
+X *BufToX(BUF *b, bool text);
+void FreeX509(X509 *x509);
+void FreeX(X *x);
+BIO *XToBio(X *x, bool text);
+BUF *XToBuf(X *x, bool text);
+K *BioToK(BIO *bio, bool private_key, bool text, char *password);
+int PKeyPasswordCallbackFunction(char *buf, int bufsize, int verify, void *param);
+void FreePKey(EVP_PKEY *pkey);
+void FreeK(K *k);
+K *BufToK(BUF *b, bool private_key, bool text, char *password);
+bool IsEncryptedK(BUF *b, bool private_key);
+bool IsBase64(BUF *b);
+BIO *KToBio(K *k, bool text, char *password);
+BUF *KToBuf(K *k, bool text, char *password);
+X *FileToX(char *filename);
+X *FileToXW(wchar_t *filename);
+bool XToFile(X *x, char *filename, bool text);
+bool XToFileW(X *x, wchar_t *filename, bool text);
+K *FileToK(char *filename, bool private_key, char *password);
+K *FileToKW(wchar_t *filename, bool private_key, char *password);
+bool KToFile(K *k, char *filename, bool text, char *password);
+bool KToFileW(K *k, wchar_t *filename, bool text, char *password);
+bool CheckXandK(X *x, K *k);
+bool CompareX(X *x1, X *x2);
+NAME *X509NameToName(void *xn);
+wchar_t *GetUniStrFromX509Name(void *xn, int nid);
+void LoadXNames(X *x);
+void FreeXNames(X *x);
+void FreeName(NAME *n);
+bool CompareName(NAME *n1, NAME *n2);
+K *GetKFromX(X *x);
+bool CheckSignature(X *x, K *k);
+X *X509ToX(X509 *x509);
+bool CheckX(X *x, X *x_issuer);
+bool Asn1TimeToSystem(SYSTEMTIME *s, void *asn1_time);
+bool StrToSystem(SYSTEMTIME *s, char *str);
+UINT64 Asn1TimeToUINT64(void *asn1_time);
+bool SystemToAsn1Time(void *asn1_time, SYSTEMTIME *s);
+bool UINT64ToAsn1Time(void *asn1_time, UINT64 t);
+bool SystemToStr(char *str, UINT size, SYSTEMTIME *s);
+void LoadXDates(X *x);
+bool CheckXDate(X *x, UINT64 current_system_time);
+bool CheckXDateNow(X *x);
+NAME *NewName(wchar_t *common_name, wchar_t *organization, wchar_t *unit,
+			  wchar_t *country, wchar_t *state, wchar_t *local);
+void *NameToX509Name(NAME *nm);
+void FreeX509Name(void *xn);
+bool AddX509Name(void *xn, int nid, wchar_t *str);
+X509 *NewRootX509(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial);
+X *NewRootX(K *pub, K *priv, NAME *name, UINT days, X_SERIAL *serial);
+X509 *NewX509(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial);
+X *NewX(K *pub, K *priv, X *ca, NAME *name, UINT days, X_SERIAL *serial);
+UINT GetDaysUntil2038();
+X_SERIAL *NewXSerial(void *data, UINT size);
+void FreeXSerial(X_SERIAL *serial);
+char *ByteToStr(BYTE *src, UINT src_size);
+P12 *BioToP12(BIO *bio);
+P12 *PKCS12ToP12(PKCS12 *pkcs12);
+P12 *BufToP12(BUF *b);
+BIO *P12ToBio(P12 *p12);
+BUF *P12ToBuf(P12 *p12);
+void FreePKCS12(PKCS12 *pkcs12);
+void FreeP12(P12 *p12);
+P12 *FileToP12(char *filename);
+P12 *FileToP12W(wchar_t *filename);
+bool P12ToFile(P12 *p12, char *filename);
+bool P12ToFileW(P12 *p12, wchar_t *filename);
+bool ParseP12(P12 *p12, X **x, K **k, char *password);
+bool IsEncryptedP12(P12 *p12);
+P12 *NewP12(X *x, K *k, char *password);
+X *CloneX(X *x);
+K *CloneK(K *k);
+void FreeCryptLibrary();
+void GetPrintNameFromX(wchar_t *str, UINT size, X *x);
+void GetPrintNameFromXA(char *str, UINT size, X *x);
+void GetPrintNameFromName(wchar_t *str, UINT size, NAME *name);
+void GetAllNameFromX(wchar_t *str, UINT size, X *x);
+void GetAllNameFromA(char *str, UINT size, X *x);
+void GetAllNameFromName(wchar_t *str, UINT size, NAME *name);
+void GetAllNameFromNameEx(wchar_t *str, UINT size, NAME *name);
+void GetAllNameFromXEx(wchar_t *str, UINT size, X *x);
+void GetAllNameFromXExA(char *str, UINT size, X *x);
+BUF *BigNumToBuf(BIGNUM *bn);
+BIGNUM *BinToBigNum(void *data, UINT size);
+BIGNUM *BufToBigNum(BUF *b);
+X_SERIAL *CloneXSerial(X_SERIAL *src);
+bool CompareXSerial(X_SERIAL *s1, X_SERIAL *s2);
+void GetXDigest(X *x, UCHAR *buf, bool sha1);
+NAME *CopyName(NAME *n);
+
+
+bool RsaGen(K **priv, K **pub, UINT bit);
+bool RsaCheck();
+bool RsaCheckEx();
+bool RsaPublicEncrypt(void *dst, void *src, UINT size, K *k);
+bool RsaPrivateDecrypt(void *dst, void *src, UINT size, K *k);
+bool RsaPrivateEncrypt(void *dst, void *src, UINT size, K *k);
+bool RsaPublicDecrypt(void *dst, void *src, UINT size, K *k);
+bool RsaSign(void *dst, void *src, UINT size, K *k);
+bool RsaSignEx(void *dst, void *src, UINT size, K *k, UINT bits);
+bool HashForSign(void *dst, UINT dst_size, void *src, UINT src_size);
+bool RsaVerify(void *data, UINT data_size, void *sign, K *k);
+bool RsaVerifyEx(void *data, UINT data_size, void *sign, K *k, UINT bits);
+UINT RsaPublicSize(K *k);
+void RsaPublicToBin(K *k, void *data);
+BUF *RsaPublicToBuf(K *k);
+K *RsaBinToPublic(void *data, UINT size);
+
+X_CRL *FileToXCrl(char *filename);
+X_CRL *FileToXCrlW(wchar_t *filename);
+X_CRL *BufToXCrl(BUF *b);
+void FreeXCrl(X_CRL *r);
+bool IsXRevokedByXCrl(X *x, X_CRL *r);
+bool IsXRevoked(X *x);
+
+
+
+void OpenSSL_InitLock();
+void OpenSSL_FreeLock();
+void OpenSSL_Lock(int mode, int n, const char *file, int line);
+unsigned long OpenSSL_Id(void);
+void FreeOpenSSLThreadState();
+
+#ifdef	ENCRYPT_C
+// 内部関数
+
+
+#endif	// ENCRYPT_C
+
+#endif	// ENCRYPT_H
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/FileIO.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/FileIO.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/FileIO.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,2234 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// FileIO.c
+// ファイル入出力コード
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+static char exe_file_name[MAX_SIZE] = "/tmp/a.out";
+static wchar_t exe_file_name_w[MAX_SIZE] = L"/tmp/a.out";
+static LIST *hamcore = NULL;
+static IO *hamcore_io = NULL;
+
+
+// ファイルを保存する
+bool SaveFileW(wchar_t *name, void *data, UINT size)
+{
+	IO *io;
+	// 引数チェック
+	if (name == NULL || (data == NULL && size != 0))
+	{
+		return false;
+	}
+
+	io = FileCreateW(name);
+	if (io == NULL)
+	{
+		return false;
+	}
+
+	if (FileWrite(io, data, size) == false)
+	{
+		FileClose(io);
+		return false;
+	}
+
+	FileClose(io);
+
+	return true;
+}
+bool SaveFile(char *name, void *data, UINT size)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = SaveFileW(name_w, data, size);
+
+	Free(name_w);
+
+	return ret;
+}
+
+// ファイルが存在するかどうか確認する
+bool IsFile(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = IsFileW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool IsFileW(wchar_t *name)
+{
+	IO *io;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	io = FileOpenExW(name, false, false);
+	if (io == NULL)
+	{
+		return false;
+	}
+
+	FileClose(io);
+
+	return true;
+}
+
+// ファイルを置換してリネームする
+bool FileReplaceRename(char *old_name, char *new_name)
+{
+	wchar_t *old_name_w = CopyStrToUni(old_name);
+	wchar_t *new_name_w = CopyStrToUni(new_name);
+	bool ret = FileReplaceRenameW(old_name_w, new_name_w);
+
+	Free(old_name_w);
+	Free(new_name_w);
+
+	return ret;
+}
+bool FileReplaceRenameW(wchar_t *old_name, wchar_t *new_name)
+{
+	// 引数チェック
+	if (old_name == NULL || new_name == NULL)
+	{
+		return false;
+	}
+
+	if (FileCopyW(old_name, new_name) == false)
+	{
+		return false;
+	}
+
+	FileDeleteW(old_name);
+
+	return true;
+}
+
+// ファイル名を安全な名前にする
+void ConvertSafeFileName(char *dst, UINT size, char *src)
+{
+	UINT i;
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return;
+	}
+
+	StrCpy(dst, size, src);
+	for (i = 0;i < StrLen(dst);i++)
+	{
+		if (IsSafeChar(dst[i]) == false)
+		{
+			dst[i] = '_';
+		}
+	}
+}
+void ConvertSafeFileNameW(wchar_t *dst, UINT size, wchar_t *src)
+{
+	UINT i;
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return;
+	}
+
+	UniStrCpy(dst, size, src);
+	for (i = 0;i < UniStrLen(dst);i++)
+	{
+		if (UniIsSafeChar(dst[i]) == false)
+		{
+			dst[i] = L'_';
+		}
+	}
+}
+
+// ディスクの空き容量を取得する
+bool GetDiskFree(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)
+{
+	bool ret;
+	// 引数チェック
+	if (path == NULL)
+	{
+		path = "./";
+	}
+
+#ifdef	OS_WIN32
+	ret = Win32GetDiskFree(path, free_size, used_size, total_size);
+#else	// OS_WIN32
+	ret = UnixGetDiskFree(path, free_size, used_size, total_size);
+#endif	// OS_WIN32
+
+	return ret;
+}
+bool GetDiskFreeW(wchar_t *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)
+{
+	bool ret;
+	// 引数チェック
+	if (path == NULL)
+	{
+		path = L"./";
+	}
+
+#ifdef	OS_WIN32
+	ret = Win32GetDiskFreeW(path, free_size, used_size, total_size);
+#else	// OS_WIN32
+	ret = UnixGetDiskFreeW(path, free_size, used_size, total_size);
+#endif	// OS_WIN32
+
+	return ret;
+}
+
+// ディレクトリの列挙
+DIRLIST *EnumDirEx(char *dirname, COMPARE *compare)
+{
+	wchar_t *dirname_w = CopyStrToUni(dirname);
+	DIRLIST *ret = EnumDirExW(dirname_w, compare);
+
+	Free(dirname_w);
+
+	return ret;
+}
+DIRLIST *EnumDirExW(wchar_t *dirname, COMPARE *compare)
+{
+	DIRLIST *d = NULL;
+	// 引数チェック
+	if (dirname == NULL)
+	{
+		dirname = L"./";
+	}
+
+	if (compare == NULL)
+	{
+		compare = CompareDirListByName;
+	}
+
+#ifdef	OS_WIN32
+	d = Win32EnumDirExW(dirname, compare);
+#else	// OS_WIN32
+	d = UnixEnumDirExW(dirname, compare);
+#endif	// OS_WIN32
+
+	return d;
+}
+DIRLIST *EnumDir(char *dirname)
+{
+	return EnumDirEx(dirname, NULL);
+}
+DIRLIST *EnumDirW(wchar_t *dirname)
+{
+	return EnumDirExW(dirname, NULL);
+}
+
+// DIRLIST リストの比較
+int CompareDirListByName(void *p1, void *p2)
+{
+	DIRENT *d1, *d2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	d1 = *(DIRENT **)p1;
+	d2 = *(DIRENT **)p2;
+	if (d1 == NULL || d2 == NULL)
+	{
+		return 0;
+	}
+	return UniStrCmpi(d1->FileNameW, d2->FileNameW);
+}
+
+// ディレクトリ列挙の解放
+void FreeDir(DIRLIST *d)
+{
+	UINT i;
+	// 引数チェック
+	if (d == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < d->NumFiles;i++)
+	{
+		DIRENT *f = d->File[i];
+		Free(f->FileName);
+		Free(f->FileNameW);
+		Free(f);
+	}
+	Free(d->File);
+	Free(d);
+}
+
+
+// ファイル名を安全にする
+void UniSafeFileName(wchar_t *name)
+{
+	UINT i, len, dlen;
+	static wchar_t *danger_str = L"\\/:*?\"<>|";
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	dlen = UniStrLen(danger_str);
+	len = UniStrLen(name);
+
+	for (i = 0;i < len;i++)
+	{
+		wchar_t c = name[i];
+		UINT j;
+		for (j = 0;j < dlen;j++)
+		{
+			if (c == danger_str[j])
+			{
+				c = L'_';
+			}
+		}
+		name[i] = c;
+	}
+}
+void SafeFileNameW(wchar_t *name)
+{
+	UniSafeFileName(name);
+}
+
+// HamCore の読み込み
+BUF *ReadHamcoreW(wchar_t *filename)
+{
+	char *filename_a = CopyUniToStr(filename);
+	BUF *ret;
+
+	ret = ReadHamcore(filename_a);
+
+	Free(filename_a);
+
+	return ret;
+}
+BUF *ReadHamcore(char *name)
+{
+	wchar_t tmp[MAX_SIZE];
+	wchar_t exe_dir[MAX_SIZE];
+	BUF *b;
+	char filename[MAX_PATH];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	if (name[0] == '|')
+	{
+		name++;
+	}
+
+	if (name[0] == '/' || name[0] == '\\')
+	{
+		name++;
+	}
+
+	StrCpy(filename, sizeof(filename), name);
+
+	ReplaceStrEx(filename, sizeof(filename), filename, "/", "\\", true);
+
+	if (MayaquaIsMinimalMode())
+	{
+		return NULL;
+	}
+
+	// ローカルディスクの hamcore/ ディレクトリにファイルがあればそれを読み込む
+	GetExeDirW(exe_dir, sizeof(exe_dir));
+
+	UniFormat(tmp, sizeof(tmp), L"%s/%S/%S", exe_dir, HAMCORE_DIR_NAME, filename);
+
+	b = ReadDumpW(tmp);
+	if (b != NULL)
+	{
+		return b;
+	}
+
+	// 無い場合は HamCore ファイルシステムから探す
+	LockList(hamcore);
+	{
+		HC t, *c;
+		UINT i;
+
+		Zero(&t, sizeof(t));
+		t.FileName = filename;
+		c = Search(hamcore, &t);
+
+		if (c == NULL)
+		{
+			// ファイルが存在しない
+			b = NULL;
+		}
+		else
+		{
+			// ファイルが存在する
+			if (c->Buffer != NULL)
+			{
+				// 既に読み込まれている
+				b = NewBuf();
+				WriteBuf(b, c->Buffer, c->Size);
+				SeekBuf(b, 0, 0);
+				c->LastAccess = Tick64();
+			}
+			else
+			{
+				// 読み込まれていないのでファイルから読み込む
+				if (FileSeek(hamcore_io, 0, c->Offset) == false)
+				{
+					// シークに失敗した
+					b = NULL;
+				}
+				else
+				{
+					// 圧縮データを読み込む
+					void *data = Malloc(c->SizeCompressed);
+					if (FileRead(hamcore_io, data, c->SizeCompressed) == false)
+					{
+						// 読み込みに失敗した
+						Free(data);
+						b = NULL;
+					}
+					else
+					{
+						// 展開する
+						c->Buffer = ZeroMalloc(c->Size);
+						if (Uncompress(c->Buffer, c->Size, data, c->SizeCompressed) != c->Size)
+						{
+							// 展開に失敗した
+							Free(data);
+							Free(c->Buffer);
+							b = NULL;
+						}
+						else
+						{
+							// 成功した
+							Free(data);
+							b = NewBuf();
+							WriteBuf(b, c->Buffer, c->Size);
+							SeekBuf(b, 0, 0);
+							c->LastAccess = Tick64();
+						}
+					}
+				}
+			}
+		}
+
+		// 有効期限の切れたキャッシュを削除する
+		for (i = 0;i < LIST_NUM(hamcore);i++)
+		{
+			HC *c = LIST_DATA(hamcore, i);
+
+			if (c->Buffer != NULL)
+			{
+				if (((c->LastAccess + HAMCORE_CACHE_EXPIRES) <= Tick64()) ||
+					(StartWith(c->FileName, "Li")))
+				{
+					Free(c->Buffer);
+					c->Buffer = NULL;
+				}
+			}
+		}
+	}
+	UnlockList(hamcore);
+
+	return b;
+}
+
+// HamCore ファイルシステムの初期化
+void InitHamcore()
+{
+	wchar_t tmp[MAX_PATH];
+	wchar_t tmp2[MAX_PATH];
+	wchar_t exe_dir[MAX_PATH];
+	UINT i, num;
+	char header[HAMCORE_HEADER_SIZE];
+
+	hamcore = NewList(CompareHamcore);
+
+	if (MayaquaIsMinimalMode())
+	{
+		return;
+	}
+
+	GetExeDirW(exe_dir, sizeof(exe_dir));
+	UniFormat(tmp, sizeof(tmp), L"%s/%S", exe_dir, HAMCORE_FILE_NAME);
+
+	UniFormat(tmp2, sizeof(tmp2), L"%s/%S", exe_dir, HAMCORE_FILE_NAME_2);
+
+	// _hamcore.utvpn がある場合は hamcore.utvpn に上書きする
+	FileReplaceRenameW(tmp2, tmp);
+
+	// hamcore.utvpn ファイルがあれば読み込む
+	hamcore_io = FileOpenW(tmp, false);
+	if (hamcore_io == NULL)
+	{
+		// 無い場合は別の場所を探す
+#ifdef	OS_WIN32
+		UniFormat(tmp, sizeof(tmp), L"%S/%S", MsGetSystem32Dir(), HAMCORE_FILE_NAME);
+#else	// OS_WIN32
+		UniFormat(tmp, sizeof(tmp), L"/bin/%S", HAMCORE_FILE_NAME);
+#endif	// OS_WIN32
+
+		hamcore_io = FileOpenW(tmp, false);
+		if (hamcore_io == NULL)
+		{
+			return;
+		}
+	}
+
+	// ファイルヘッダを読み込む
+	Zero(header, sizeof(header));
+	FileRead(hamcore_io, header, HAMCORE_HEADER_SIZE);
+
+	if (Cmp(header, HAMCORE_HEADER_DATA, HAMCORE_HEADER_SIZE) != 0)
+	{
+		// ヘッダ不正
+		FileClose(hamcore_io);
+		hamcore_io = NULL;
+		return;
+	}
+
+	// ファイル個数
+	num = 0;
+	FileRead(hamcore_io, &num, sizeof(num));
+	num = Endian32(num);
+	for (i = 0;i < num;i++)
+	{
+		// ファイル名
+		char tmp[MAX_SIZE];
+		UINT str_size = 0;
+		HC *c;
+
+		FileRead(hamcore_io, &str_size, sizeof(str_size));
+		str_size = Endian32(str_size);
+		if (str_size >= 1)
+		{
+			str_size--;
+		}
+
+		Zero(tmp, sizeof(tmp));
+		FileRead(hamcore_io, tmp, str_size);
+
+		c = ZeroMalloc(sizeof(HC));
+		c->FileName = CopyStr(tmp);
+
+		FileRead(hamcore_io, &c->Size, sizeof(UINT));
+		c->Size = Endian32(c->Size);
+
+		FileRead(hamcore_io, &c->SizeCompressed, sizeof(UINT));
+		c->SizeCompressed = Endian32(c->SizeCompressed);
+
+		FileRead(hamcore_io, &c->Offset, sizeof(UINT));
+		c->Offset = Endian32(c->Offset);
+
+		Insert(hamcore, c);
+	}
+}
+
+// HamCore ファイルシステムの解放
+void FreeHamcore()
+{
+	UINT i;
+	for (i = 0;i < LIST_NUM(hamcore);i++)
+	{
+		HC *c = LIST_DATA(hamcore, i);
+		Free(c->FileName);
+		if (c->Buffer != NULL)
+		{
+			Free(c->Buffer);
+		}
+		Free(c);
+	}
+	ReleaseList(hamcore);
+
+	FileClose(hamcore_io);
+	hamcore_io = NULL;
+	hamcore = NULL;
+}
+
+// Hamcore のビルド
+void BuildHamcore()
+{
+	BUF *b;
+	char tmp[MAX_SIZE];
+	char exe_dir[MAX_SIZE];
+	char *s;
+	bool ok = true;
+	LIST *o;
+	UINT i;
+
+	GetExeDir(exe_dir, sizeof(exe_dir));
+	Format(tmp, sizeof(tmp), "%s/%s", exe_dir, HAMCORE_TEXT_NAME);
+
+	b = ReadDump(tmp);
+	if (b == NULL)
+	{
+		Print("Failed to open %s.\n", tmp);
+		return;
+	}
+
+	o = NewListFast(CompareHamcore);
+
+	while ((s = CfgReadNextLine(b)) != NULL)
+	{
+		char tmp[MAX_SIZE];
+		BUF *b;
+		Trim(s);
+
+		Format(tmp, sizeof(tmp), "%s/%s/%s", exe_dir, HAMCORE_DIR_NAME, s);
+
+		b = ReadDump(tmp);
+		if (b == NULL)
+		{
+			Print("Failed to open %s.\n", s);
+			ok = false;
+		}
+		else
+		{
+			HC *c = ZeroMalloc(sizeof(HC));
+			UINT tmp_size;
+			void *tmp;
+			c->FileName = CopyStr(s);
+			c->Size = b->Size;
+			tmp_size = CalcCompress(c->Size);
+			tmp = Malloc(tmp_size);
+			c->SizeCompressed = Compress(tmp, tmp_size, b->Buf, b->Size);
+			c->Buffer = tmp;
+			Insert(o, c);
+			Print("%s: %u -> %u\n", s, c->Size, c->SizeCompressed);
+			FreeBuf(b);
+		}
+
+		Free(s);
+	}
+
+	if (ok)
+	{
+		// 各ファイルのバッファのオフセットを計算する
+		UINT i, z;
+		char tmp[MAX_SIZE];
+		BUF *b;
+		z = 0;
+		z += HAMCORE_HEADER_SIZE;
+		// ファイルの個数
+		z += sizeof(UINT);
+		// まずファイルテーブル
+		for (i = 0;i < LIST_NUM(o);i++)
+		{
+			HC *c = LIST_DATA(o, i);
+			// ファイル名
+			z += StrLen(c->FileName) + sizeof(UINT);
+			// ファイルサイズ
+			z += sizeof(UINT);
+			z += sizeof(UINT);
+			// オフセットデータ
+			z += sizeof(UINT);
+		}
+		// ファイル本体
+		for (i = 0;i < LIST_NUM(o);i++)
+		{
+			HC *c = LIST_DATA(o, i);
+			// バッファ本体
+			c->Offset = z;
+			printf("%s: offset: %u\n", c->FileName, c->Offset);
+			z += c->SizeCompressed;
+		}
+		// 書き込み
+		b = NewBuf();
+		// ヘッダ
+		WriteBuf(b, HAMCORE_HEADER_DATA, HAMCORE_HEADER_SIZE);
+		WriteBufInt(b, LIST_NUM(o));
+		for (i = 0;i < LIST_NUM(o);i++)
+		{
+			HC *c = LIST_DATA(o, i);
+			// ファイル名
+			WriteBufStr(b, c->FileName);
+			// ファイルサイズ
+			WriteBufInt(b, c->Size);
+			WriteBufInt(b, c->SizeCompressed);
+			// オフセット
+			WriteBufInt(b, c->Offset);
+		}
+		// 本体
+		for (i = 0;i < LIST_NUM(o);i++)
+		{
+			HC *c = LIST_DATA(o, i);
+			WriteBuf(b, c->Buffer, c->SizeCompressed);
+		}
+		// 書き込み
+		Format(tmp, sizeof(tmp), "%s/%s", exe_dir, HAMCORE_FILE_NAME "__");
+		Print("Writing %s...\n", tmp);
+		FileDelete(tmp);
+		DumpBuf(b, tmp);
+		FreeBuf(b);
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		HC *c = LIST_DATA(o, i);
+		Free(c->Buffer);
+		Free(c->FileName);
+		Free(c);
+	}
+
+	ReleaseList(o);
+
+	FreeBuf(b);
+}
+
+// HC の比較
+int CompareHamcore(void *p1, void *p2)
+{
+	HC *c1, *c2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	c1 = *(HC **)p1;
+	c2 = *(HC **)p2;
+	if (c1 == NULL || c2 == NULL)
+	{
+		return 0;
+	}
+	return StrCmpi(c1->FileName, c2->FileName);
+}
+
+// EXE ファイルがあるディレクトリ名の取得
+void GetExeDir(char *name, UINT size)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	GetDirNameFromFilePath(name, size, exe_file_name);
+}
+void GetExeDirW(wchar_t *name, UINT size)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	GetDirNameFromFilePathW(name, size, exe_file_name_w);
+}
+
+// EXE ファイル名の取得
+void GetExeName(char *name, UINT size)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	StrCpy(name, size, exe_file_name);
+}
+void GetExeNameW(wchar_t *name, UINT size)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	UniStrCpy(name, size, exe_file_name_w);
+}
+
+// EXE ファイル名の取得初期化
+void InitGetExeName(char *arg)
+{
+	wchar_t *arg_w = NULL;
+	// 引数チェック
+	if (arg == NULL)
+	{
+		arg = "./a.out";
+	}
+
+	arg_w = CopyUtfToUni(arg);
+
+#ifdef	OS_WIN32
+	Win32GetExeNameW(exe_file_name_w, sizeof(exe_file_name_w));
+#else	// OS_WIN32
+	UnixGetExeNameW(exe_file_name_w, sizeof(exe_file_name_w), arg_w);
+#endif	// OS_WIN32
+
+	UniToStr(exe_file_name, sizeof(exe_file_name), exe_file_name_w);
+
+	Free(arg_w);
+}
+
+// Unix における実行可能バイナリファイルのフルパスの取得
+void UnixGetExeNameW(wchar_t *name, UINT size, wchar_t *arg)
+{
+	UNI_TOKEN_LIST *t;
+	char *path_str;
+	wchar_t *path_str_w;
+	bool ok = false;
+	// 引数チェック
+	if (name == NULL || arg == NULL)
+	{
+		return;
+	}
+
+	path_str = GetCurrentPathEnvStr();
+	path_str_w = CopyUtfToUni(path_str);
+
+	t = ParseSplitedPathW(path_str_w);
+
+	if (t != NULL)
+	{
+		UINT i;
+		for (i = 0;i < t->NumTokens;i++)
+		{
+			wchar_t *s = t->Token[i];
+			wchar_t tmp[MAX_SIZE];
+
+			ConbinePathW(tmp, sizeof(tmp), s, arg);
+
+			if (IsFileExistsInnerW(tmp))
+			{
+#ifdef	OS_UNIX
+				if (UnixCheckExecAccessW(tmp) == false)
+				{
+					continue;
+				}
+#endif	// OS_UNIX
+				ok = true;
+				UniStrCpy(name, size, tmp);
+				break;
+			}
+		}
+
+		UniFreeToken(t);
+	}
+
+	Free(path_str);
+	Free(path_str_w);
+
+	if (ok == false)
+	{
+		// パスの検索に失敗した場合
+#ifdef	OS_UNIX
+		UnixGetCurrentDirW(name, size);
+#else	// OS_UNIX
+		Win32GetCurrentDirW(name, size);
+#endif	// OS_UNIX
+		ConbinePathW(name, size, name, arg);
+	}
+}
+
+// 安全なファイル名を生成する
+void MakeSafeFileName(char *dst, UINT size, char *src)
+{
+	char tmp[MAX_PATH];
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return;
+	}
+
+	StrCpy(tmp, sizeof(tmp), src);
+	ReplaceStrEx(tmp, sizeof(tmp), tmp, "..", "__", false);
+	ReplaceStrEx(tmp, sizeof(tmp), tmp, "/", "_", false);
+	ReplaceStrEx(tmp, sizeof(tmp), tmp, "\\", "_", false);
+	ReplaceStrEx(tmp, sizeof(tmp), tmp, "@", "_", false);
+	ReplaceStrEx(tmp, sizeof(tmp), tmp, "|", "_", false);
+
+	StrCpy(dst, size, tmp);
+}
+void MakeSafeFileNameW(wchar_t *dst, UINT size, wchar_t *src)
+{
+	wchar_t tmp[MAX_PATH];
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return;
+	}
+
+	UniStrCpy(tmp, sizeof(tmp), src);
+	UniReplaceStrEx(tmp, sizeof(tmp), tmp, L"..", L"__", false);
+	UniReplaceStrEx(tmp, sizeof(tmp), tmp, L"/", L"_", false);
+	UniReplaceStrEx(tmp, sizeof(tmp), tmp, L"\\", L"_", false);
+	UniReplaceStrEx(tmp, sizeof(tmp), tmp, L"@", L"_", false);
+	UniReplaceStrEx(tmp, sizeof(tmp), tmp, L"|", L"_", false);
+
+	UniStrCpy(dst, size, tmp);
+}
+
+// ファイルパスからファイル名を取得する
+void GetFileNameFromFilePathW(wchar_t *dst, UINT size, wchar_t *filepath)
+{
+	wchar_t tmp[MAX_SIZE];
+	UINT i, len, wp;
+	// 引数チェック
+	if (dst == NULL || filepath == NULL)
+	{
+		return;
+	}
+
+	len = MIN(UniStrLen(filepath), (MAX_SIZE - 2));
+	wp = 0;
+
+	for (i = 0;i < (len + 1);i++)
+	{
+		wchar_t c = filepath[i];
+
+		switch (c)
+		{
+		case L'\\':
+		case L'/':
+		case 0:
+			tmp[wp] = 0;
+			wp = 0;
+			break;
+
+		default:
+			tmp[wp] = c;
+			wp++;
+			break;
+		}
+	}
+
+	UniStrCpy(dst, size, tmp);
+}
+void GetFileNameFromFilePath(char *dst, UINT size, char *filepath)
+{
+	char tmp[MAX_SIZE];
+	UINT i, len, wp;
+	// 引数チェック
+	if (dst == NULL || filepath == NULL)
+	{
+		return;
+	}
+
+	len = MIN(StrLen(filepath), (MAX_SIZE - 2));
+	wp = 0;
+
+	for (i = 0;i < (len + 1);i++)
+	{
+		char c = filepath[i];
+
+		switch (c)
+		{
+		case '\\':
+		case '/':
+		case 0:
+			tmp[wp] = 0;
+			wp = 0;
+			break;
+
+		default:
+			tmp[wp] = c;
+			wp++;
+			break;
+		}
+	}
+
+	StrCpy(dst, size, tmp);
+}
+void GetDirNameFromFilePathW(wchar_t *dst, UINT size, wchar_t *filepath)
+{
+	wchar_t tmp[MAX_SIZE];
+	UINT wp;
+	UINT i;
+	UINT len;
+	// 引数チェック
+	if (dst == NULL || filepath == NULL)
+	{
+		return;
+	}
+
+	UniStrCpy(tmp, sizeof(tmp), filepath);
+	if (UniEndWith(tmp, L"\\") || UniEndWith(tmp, L"/"))
+	{
+		tmp[UniStrLen(tmp) - 1] = 0;
+	}
+
+	len = UniStrLen(tmp);
+
+	UniStrCpy(dst, size, L"");
+
+	wp = 0;
+
+	for (i = 0;i < len;i++)
+	{
+		wchar_t c = tmp[i];
+		if (c == L'/' || c == L'\\')
+		{
+			tmp[wp++] = 0;
+			wp = 0;
+			UniStrCat(dst, size, tmp);
+			tmp[wp++] = c;
+		}
+		else
+		{
+			tmp[wp++] = c;
+		}
+	}
+
+	if (UniStrLen(dst) == 0)
+	{
+		UniStrCpy(dst, size, L"/");
+	}
+
+	NormalizePathW(dst, size, dst);
+}
+
+// ファイルパスからディレクトリ名を取得する
+void GetDirNameFromFilePath(char *dst, UINT size, char *filepath)
+{
+	char tmp[MAX_SIZE];
+	UINT wp;
+	UINT i;
+	UINT len;
+	// 引数チェック
+	if (dst == NULL || filepath == NULL)
+	{
+		return;
+	}
+
+	StrCpy(tmp, sizeof(tmp), filepath);
+	if (EndWith(tmp, "\\") || EndWith(tmp, "/"))
+	{
+		tmp[StrLen(tmp) - 1] = 0;
+	}
+
+	len = StrLen(tmp);
+
+	StrCpy(dst, size, "");
+
+	wp = 0;
+
+	for (i = 0;i < len;i++)
+	{
+		char c = tmp[i];
+		if (c == '/' || c == '\\')
+		{
+			tmp[wp++] = 0;
+			wp = 0;
+			StrCat(dst, size, tmp);
+			tmp[wp++] = c;
+		}
+		else
+		{
+			tmp[wp++] = c;
+		}
+	}
+
+	if (StrLen(dst) == 0)
+	{
+		StrCpy(dst, size, "/");
+	}
+
+	NormalizePath(dst, size, dst);
+}
+
+// 2 つのパスを結合する
+void ConbinePath(char *dst, UINT size, char *dirname, char *filename)
+{
+	wchar_t dst_w[MAX_PATH];
+	wchar_t *dirname_w = CopyStrToUni(dirname);
+	wchar_t *filename_w = CopyStrToUni(filename);
+
+	ConbinePathW(dst_w, sizeof(dst_w), dirname_w, filename_w);
+
+	Free(dirname_w);
+	Free(filename_w);
+
+	UniToStr(dst, size, dst_w);
+}
+void ConbinePathW(wchar_t *dst, UINT size, wchar_t *dirname, wchar_t *filename)
+{
+	bool is_full_path;
+	wchar_t tmp[MAX_SIZE];
+	wchar_t filename_ident[MAX_SIZE];
+	// 引数チェック
+	if (dst == NULL || dirname == NULL || filename == NULL)
+	{
+		return;
+	}
+
+	NormalizePathW(filename_ident, sizeof(filename_ident), filename);
+
+	is_full_path = false;
+
+	if (UniStartWith(filename_ident, L"\\") || UniStartWith(filename_ident, L"/"))
+	{
+		is_full_path = true;
+	}
+
+	filename = &filename_ident[0];
+
+#ifdef	OS_WIN32
+	if (UniStrLen(filename) >= 2)
+	{
+		if ((L'a' <= filename[0] && filename[0] <= L'z') || (L'A' <= filename[0] && filename[0] <= L'Z'))
+		{
+			if (filename[1] == L':')
+			{
+				is_full_path = true;
+			}
+		}
+	}
+#endif	// OS_WIN32
+
+	if (is_full_path == false)
+	{
+		UniStrCpy(tmp, sizeof(tmp), dirname);
+		if (UniEndWith(tmp, L"/") == false && UniEndWith(tmp, L"\\") == false)
+		{
+			UniStrCat(tmp, sizeof(tmp), L"/");
+		}
+		UniStrCat(tmp, sizeof(tmp), filename);
+	}
+	else
+	{
+		UniStrCpy(tmp, sizeof(tmp), filename);
+	}
+
+	NormalizePathW(dst, size, tmp);
+}
+void CombinePath(char *dst, UINT size, char *dirname, char *filename)
+{
+	ConbinePath(dst, size, dirname, filename);
+}
+void CombinePathW(wchar_t *dst, UINT size, wchar_t *dirname, wchar_t *filename)
+{
+	ConbinePathW(dst, size, dirname, filename);
+}
+
+// ファイルが存在するかどうか確認する
+bool IsFileExists(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = IsFileExistsW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool IsFileExistsW(wchar_t *name)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	InnerFilePathW(tmp, sizeof(tmp), name);
+
+	return IsFileExistsInnerW(tmp);
+}
+bool IsFileExistsInner(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = IsFileExistsInnerW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool IsFileExistsInnerW(wchar_t *name)
+{
+	IO *o;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	o = FileOpenInnerW(name, false, false);
+	if (o == NULL)
+	{
+		return false;
+	}
+
+	FileClose(o);
+
+	return true;
+}
+
+// 現在の環境変数 PATH の内容を取得
+char *GetCurrentPathEnvStr()
+{
+	char tmp[1024];
+	char *tag_name;
+
+#ifdef	OS_WIN32
+	tag_name = "Path";
+#else	// OS_WIN32
+	tag_name = "PATH";
+#endif	// OS_WIN32
+
+	if (GetEnv(tag_name, tmp, sizeof(tmp)) == false)
+	{
+#ifdef	OS_WIN32
+		Win32GetCurrentDir(tmp, sizeof(tmp));
+#else	// OS_WIN32
+		UnixGetCurrentDir(tmp, sizeof(tmp));
+#endif	// OS_WIN32
+	}
+
+	return CopyStr(tmp);
+}
+
+// コロン文字列で区切られた複数のパスを取得する
+UNI_TOKEN_LIST *ParseSplitedPathW(wchar_t *path)
+{
+	UNI_TOKEN_LIST *ret;
+	wchar_t *tmp = UniCopyStr(path);
+	wchar_t *split_str;
+	UINT i;
+
+	UniTrim(tmp);
+	UniTrimCrlf(tmp);
+	UniTrim(tmp);
+	UniTrimCrlf(tmp);
+
+#ifdef	OS_WIN32
+	split_str = L";";
+#else	// OS_WIN32
+	split_str = L":";
+#endif	// OS_WIN32
+
+	ret = UniParseToken(tmp, split_str);
+
+	if (ret != NULL)
+	{
+		for (i = 0;i < ret->NumTokens;i++)
+		{
+			UniTrim(ret->Token[i]);
+			UniTrimCrlf(ret->Token[i]);
+			UniTrim(ret->Token[i]);
+			UniTrimCrlf(ret->Token[i]);
+		}
+	}
+
+	Free(tmp);
+
+	return ret;
+}
+TOKEN_LIST *ParseSplitedPath(char *path)
+{
+	TOKEN_LIST *ret;
+	char *tmp = CopyStr(path);
+	char *split_str;
+	UINT i;
+
+	Trim(tmp);
+	TrimCrlf(tmp);
+	Trim(tmp);
+	TrimCrlf(tmp);
+
+#ifdef	OS_WIN32
+	split_str = ";";
+#else	// OS_WIN32
+	split_str = ":";
+#endif	// OS_WIN32
+
+	ret = ParseToken(tmp, split_str);
+
+	if (ret != NULL)
+	{
+		for (i = 0;i < ret->NumTokens;i++)
+		{
+			Trim(ret->Token[i]);
+			TrimCrlf(ret->Token[i]);
+			Trim(ret->Token[i]);
+			TrimCrlf(ret->Token[i]);
+		}
+	}
+
+	Free(tmp);
+
+	return ret;
+}
+
+// 現在のディレクトリを取得する
+void GetCurrentDirW(wchar_t *name, UINT size)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+#ifdef	OS_WIN32
+	Win32GetCurrentDirW(name, size);
+#else	// OS_WIN32
+	UnixGetCurrentDirW(name, size);
+#endif	// OS_WIN32
+}
+void GetCurrentDir(char *name, UINT size)
+{
+	wchar_t name_w[MAX_PATH];
+
+	GetCurrentDirW(name_w, sizeof(name_w));
+
+	UniToStr(name, size, name_w);
+}
+
+// ファイルパスを正規化する
+void NormalizePathW(wchar_t *dst, UINT size, wchar_t *src)
+{
+	wchar_t tmp[MAX_SIZE];
+	UNI_TOKEN_LIST *t;
+	bool first_double_slash = false;
+	bool first_single_slash = false;
+	wchar_t win32_drive_char = 0;
+	bool is_full_path = false;
+	UINT i;
+	SK *sk;
+	// 引数チェック
+	if (dst == NULL || src == 0)
+	{
+		return;
+	}
+
+	// パスを変換する (Win32, UNIX 変換)
+	UniStrCpy(tmp, sizeof(tmp), src);
+	ConvertPathW(tmp);
+	UniTrim(tmp);
+
+	// 先頭が "./" や "../" で始まっている場合はカレントディレクトリに置換する
+	if (UniStartWith(tmp, L"./") || UniStartWith(tmp, L".\\") ||
+		UniStartWith(tmp, L"../") || UniStartWith(tmp, L"..\\") ||
+		UniStrCmpi(tmp, L".") == 0 || UniStrCmpi(tmp, L"..") == 0)
+	{
+		wchar_t cd[MAX_SIZE];
+		Zero(cd, sizeof(cd));
+
+#ifdef	OS_WIN32
+		Win32GetCurrentDirW(cd, sizeof(cd));
+#else	// OS_WIN32
+		UnixGetCurrentDirW(cd, sizeof(cd));
+#endif	// OS_WIN32
+
+		if (UniStartWith(tmp, L".."))
+		{
+			UniStrCat(cd, sizeof(cd), L"/../");
+			UniStrCat(cd, sizeof(cd), tmp + 2);
+		}
+		else
+		{
+			UniStrCat(cd, sizeof(cd), L"/");
+			UniStrCat(cd, sizeof(cd), tmp);
+		}
+
+		UniStrCpy(tmp, sizeof(tmp), cd);
+	}
+
+	// 先頭が "~/" で始まっている場合はホームディレクトリに置換する
+	if (UniStartWith(tmp, L"~/") || UniStartWith(tmp, L"~\\"))
+	{
+		wchar_t tmp2[MAX_SIZE];
+		GetHomeDirW(tmp2, sizeof(tmp2));
+		UniStrCat(tmp2, sizeof(tmp2), L"/");
+		UniStrCat(tmp2, sizeof(tmp2), tmp + 2);
+		UniStrCpy(tmp, sizeof(tmp), tmp2);
+	}
+
+	if (UniStartWith(tmp, L"//") || UniStartWith(tmp, L"\\\\"))
+	{
+		// 最初が "//" または "\\" で始まる
+		first_double_slash = true;
+		is_full_path = true;
+	}
+	else if (UniStartWith(tmp, L"/") || UniStartWith(tmp, L"\\"))
+	{
+		// 最初が "\" で始まる
+		first_single_slash = true;
+		is_full_path = true;
+	}
+
+	if (UniStrLen(tmp) >= 2)
+	{
+		if (tmp[1] == L':')
+		{
+			if (OS_IS_WINDOWS(GetOsInfo()->OsType))
+			{
+				// Win32 のドライブ文字列表記
+				wchar_t tmp2[MAX_SIZE];
+				is_full_path = true;
+				win32_drive_char = tmp[0];
+				UniStrCpy(tmp2, sizeof(tmp2), tmp + 2);
+				UniStrCpy(tmp, sizeof(tmp), tmp2);
+			}
+		}
+	}
+
+	if (UniStrLen(tmp) == 1 && (tmp[0] == L'/' || tmp[0] == L'\\'))
+	{
+		tmp[0] = 0;
+	}
+
+	// トークン分割
+	t = UniParseToken(tmp, L"/\\");
+
+	sk = NewSk();
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		wchar_t *s = t->Token[i];
+
+		if (UniStrCmpi(s, L".") == 0)
+		{
+			continue;
+		}
+		else if (UniStrCmpi(s, L"..") == 0)
+		{
+			if (sk->num_item >= 1 && (first_double_slash == false || sk->num_item >= 2))
+			{
+				Pop(sk);
+			}
+		}
+		else
+		{
+			Push(sk, s);
+		}
+	}
+
+	// トークン結合
+	UniStrCpy(tmp, sizeof(tmp), L"");
+
+	if (first_double_slash)
+	{
+		UniStrCat(tmp, sizeof(tmp), L"//");
+	}
+	else if (first_single_slash)
+	{
+		UniStrCat(tmp, sizeof(tmp), L"/");
+	}
+
+	if (win32_drive_char != 0)
+	{
+		wchar_t d[2];
+		d[0] = win32_drive_char;
+		d[1] = 0;
+		UniStrCat(tmp, sizeof(tmp), d);
+		UniStrCat(tmp, sizeof(tmp), L":/");
+	}
+
+	for (i = 0;i < sk->num_item;i++)
+	{
+		UniStrCat(tmp, sizeof(tmp), (wchar_t *)sk->p[i]);
+		if (i != (sk->num_item - 1))
+		{
+			UniStrCat(tmp, sizeof(tmp), L"/");
+		}
+	}
+
+	ReleaseSk(sk);
+
+	UniFreeToken(t);
+
+	ConvertPathW(tmp);
+
+	UniStrCpy(dst, size, tmp);
+}
+void NormalizePath(char *dst, UINT size, char *src)
+{
+	wchar_t dst_w[MAX_SIZE];
+	wchar_t *src_w = CopyStrToUni(src);
+
+	NormalizePathW(dst_w, sizeof(dst_w), src_w);
+
+	Free(src_w);
+
+	UniToStr(dst, size, dst_w);
+}
+
+// ファイルを閉じて削除する
+void FileCloseAndDelete(IO *o)
+{
+	wchar_t *name;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	name = CopyUniStr(o->NameW);
+	FileClose(o);
+
+	FileDeleteW(name);
+
+	Free(name);
+}
+
+// ファイル名の変更
+bool FileRename(char *old_name, char *new_name)
+{
+	wchar_t *old_name_w = CopyStrToUni(old_name);
+	wchar_t *new_name_w = CopyStrToUni(new_name);
+	bool ret = FileRenameW(old_name_w, new_name_w);
+
+	Free(old_name_w);
+	Free(new_name_w);
+
+	return ret;
+}
+bool FileRenameW(wchar_t *old_name, wchar_t *new_name)
+{
+	wchar_t tmp1[MAX_SIZE];
+	wchar_t tmp2[MAX_SIZE];
+	// 引数チェック
+	if (old_name == NULL || new_name == NULL)
+	{
+		return false;
+	}
+
+	InnerFilePathW(tmp1, sizeof(tmp1), old_name);
+	InnerFilePathW(tmp2, sizeof(tmp2), new_name);
+
+	return FileRenameInnerW(tmp1, tmp2);
+}
+bool FileRenameInner(char *old_name, char *new_name)
+{
+	wchar_t *old_name_w = CopyStrToUni(old_name);
+	wchar_t *new_name_w = CopyStrToUni(new_name);
+	bool ret = FileRenameInnerW(old_name_w, new_name_w);
+
+	Free(old_name_w);
+	Free(new_name_w);
+
+	return ret;
+}
+bool FileRenameInnerW(wchar_t *old_name, wchar_t *new_name)
+{
+	// 引数チェック
+	if (old_name == NULL || new_name == NULL)
+	{
+		return false;
+	}
+
+	return OSFileRenameW(old_name, new_name);
+}
+
+// パスの変換
+void ConvertPath(char *path)
+{
+	UINT i, len;
+#ifdef	PATH_BACKSLASH
+	char new_char = '\\';
+#else
+	char new_char = '/';
+#endif
+
+	len = StrLen(path);
+	for (i = 0;i < len;i++)
+	{
+		if (path[i] == '\\' || path[i] == '/')
+		{
+			path[i] = new_char;
+		}
+	}
+}
+void ConvertPathW(wchar_t *path)
+{
+	UINT i, len;
+#ifdef	PATH_BACKSLASH
+	wchar_t new_char = L'\\';
+#else
+	wchar_t new_char = L'/';
+#endif
+
+	len = UniStrLen(path);
+	for (i = 0;i < len;i++)
+	{
+		if (path[i] == L'\\' || path[i] == L'/')
+		{
+			path[i] = new_char;
+		}
+	}
+}
+
+// ディレクトリの削除
+bool DeleteDir(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = DeleteDirW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool DeleteDirW(wchar_t *name)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	InnerFilePathW(tmp, sizeof(tmp), name);
+
+	return DeleteDirInnerW(tmp);
+}
+bool DeleteDirInner(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = DeleteDirInnerW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool DeleteDirInnerW(wchar_t *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	return OSDeleteDirW(name);
+}
+
+// 内部ファイルパスの生成
+void InnerFilePathW(wchar_t *dst, UINT size, wchar_t *src)
+{
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return;
+	}
+
+	if (src[0] != L'@')
+	{
+		NormalizePathW(dst, size, src);
+	}
+	else
+	{
+		wchar_t dir[MAX_SIZE];
+		GetExeDirW(dir, sizeof(dir));
+		ConbinePathW(dst, size, dir, &src[1]);
+	}
+}
+void InnerFilePath(char *dst, UINT size, char *src)
+{
+	wchar_t dst_w[MAX_PATH];
+	wchar_t *src_w = CopyStrToUni(src);
+
+	InnerFilePathW(dst_w, sizeof(dst_w), src_w);
+
+	Free(src_w);
+
+	UniToStr(dst, size, dst_w);
+}
+
+// ディレクトリの再帰作成
+void MakeDirEx(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+
+	MakeDirExW(name_w);
+
+	Free(name_w);
+}
+void MakeDirExW(wchar_t *name)
+{
+	LIST *o;
+	wchar_t tmp[MAX_PATH];
+	wchar_t tmp2[MAX_PATH];
+	UINT i;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	o = NewListFast(NULL);
+
+	UniStrCpy(tmp, sizeof(tmp), name);
+	while (true)
+	{
+		wchar_t *s = CopyUniStr(tmp);
+
+		Add(o, s);
+
+		GetDirNameFromFilePathW(tmp2, sizeof(tmp2), tmp);
+
+		if (UniStrCmpi(tmp2, tmp) == 0)
+		{
+			break;
+		}
+
+		UniStrCpy(tmp, sizeof(tmp), tmp2);
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		UINT j = LIST_NUM(o) - i - 1;
+		wchar_t *s = LIST_DATA(o, j);
+
+		if (UniStrCmpi(s, L"\\") != 0 && UniStrCmpi(s, L"/") != 0)
+		{
+			MakeDirW(s);
+		}
+	}
+
+	UniFreeStrList(o);
+}
+
+// ディレクトリの作成
+bool MakeDir(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = MakeDirW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool MakeDirW(wchar_t *name)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	InnerFilePathW(tmp, sizeof(tmp), name);
+
+	return MakeDirInnerW(tmp);
+}
+bool MakeDirInner(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = MakeDirInnerW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool MakeDirInnerW(wchar_t *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	return OSMakeDirW(name);
+}
+
+// ファイルの削除
+bool FileDelete(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = FileDeleteW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool FileDeleteW(wchar_t *name)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	InnerFilePathW(tmp, sizeof(tmp), name);
+
+	return FileDeleteInnerW(tmp);
+}
+bool FileDeleteInner(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	bool ret = FileDeleteInnerW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+bool FileDeleteInnerW(wchar_t *name)
+{
+	wchar_t name2[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	UniStrCpy(name2, sizeof(name2), name);
+	ConvertPathW(name2);
+
+	return OSFileDeleteW(name2);
+}
+
+// ファイルをシークする
+bool FileSeek(IO *o, UINT mode, int offset)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return false;
+	}
+
+	if (o->HamMode == false)
+	{
+		return OSFileSeek(o->pData, mode, offset);
+	}
+	else
+	{
+		return false;
+	}
+}
+
+// ファイル名を指定してファイルサイズを取得する
+UINT FileSizeEx(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	UINT ret = FileSizeExW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+UINT FileSizeExW(wchar_t *name)
+{
+	IO *io;
+	UINT size;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return 0;
+	}
+
+	io = FileOpenW(name, false);
+	if (io == NULL)
+	{
+		return 0;
+	}
+
+	size = FileSize(io);
+
+	FileClose(io);
+
+	return size;
+}
+
+// ファイルサイズを取得する
+UINT64 FileSize64(IO *o)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return 0;
+	}
+
+	if (o->HamMode == false)
+	{
+		return OSFileSize(o->pData);
+	}
+	else
+	{
+		return (UINT64)o->HamBuf->Size;
+	}
+}
+UINT FileSize(IO *o)
+{
+	UINT64 size = (UINT)(FileSize64(o));
+
+	if (size >= 4294967296ULL)
+	{
+		size = 4294967295ULL;
+	}
+
+	return (UINT)size;
+}
+
+// ファイルから読み込む
+bool FileRead(IO *o, void *buf, UINT size)
+{
+	// 引数チェック
+	if (o == NULL || buf == NULL)
+	{
+		return false;
+	}
+
+	// KS
+	KS_INC(KS_IO_READ_COUNT);
+	KS_ADD(KS_IO_TOTAL_READ_SIZE, size);
+
+	if (size == 0)
+	{
+		return true;
+	}
+
+	if (o->HamMode == false)
+	{
+		return OSFileRead(o->pData, buf, size);
+	}
+	else
+	{
+		return ReadBuf(o->HamBuf, buf, size) == size ? true : false;
+	}
+}
+
+// ファイルに書き込む
+bool FileWrite(IO *o, void *buf, UINT size)
+{
+	// 引数チェック
+	if (o == NULL || buf == NULL)
+	{
+		return false;
+	}
+	if (o->WriteMode == false)
+	{
+		return false;
+	}
+
+	// KS
+	KS_INC(KS_IO_WRITE_COUNT);
+	KS_ADD(KS_IO_TOTAL_WRITE_SIZE, size);
+
+	if (size == 0)
+	{
+		return true;
+	}
+
+	return OSFileWrite(o->pData, buf, size);
+}
+
+// ファイルをフラッシュする
+void FileFlush(IO *o)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	if (o->HamMode)
+	{
+		return;
+	}
+
+	OSFileFlush(o->pData);
+}
+
+// ファイルを閉じる
+void FileClose(IO *o)
+{
+	FileCloseEx(o, false);
+}
+void FileCloseEx(IO *o, bool no_flush)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	if (o->HamMode == false)
+	{
+		OSFileClose(o->pData, no_flush);
+	}
+	else
+	{
+		FreeBuf(o->HamBuf);
+	}
+	Free(o);
+
+	// KS
+	KS_INC(KS_IO_CLOSE_COUNT);
+}
+
+// ファイルを作成する
+IO *FileCreateInner(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	IO *ret = FileCreateInnerW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+IO *FileCreateInnerW(wchar_t *name)
+{
+	IO *o;
+	void *p;
+	wchar_t name2[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	UniStrCpy(name2, sizeof(name2), name);
+	ConvertPathW(name2);
+
+	p = OSFileCreateW(name2);
+	if (p == NULL)
+	{
+		return NULL;
+	}
+
+	o = ZeroMalloc(sizeof(IO));
+	o->pData = p;
+	UniStrCpy(o->NameW, sizeof(o->NameW), name2);
+	UniToStr(o->Name, sizeof(o->Name), o->NameW);
+	o->WriteMode = true;
+
+	// KS
+	KS_INC(KS_IO_CREATE_COUNT);
+
+	return o;
+}
+IO *FileCreate(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	IO *ret = FileCreateW(name_w);
+
+	Free(name_w);
+
+	return ret;
+}
+IO *FileCreateW(wchar_t *name)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	InnerFilePathW(tmp, sizeof(tmp), name);
+
+	return FileCreateInnerW(tmp);
+}
+
+// ファイルにすべてのデータを書き込む
+bool FileWriteAll(char *name, void *data, UINT size)
+{
+	IO *io;
+	// 引数チェック
+	if (name == NULL || (data == NULL && size != 0))
+	{
+		return false;
+	}
+
+	io = FileCreate(name);
+
+	if (io == NULL)
+	{
+		return false;
+	}
+
+	FileWrite(io, data, size);
+
+	FileClose(io);
+
+	return true;
+}
+bool FileWriteAllW(wchar_t *name, void *data, UINT size)
+{
+	IO *io;
+	// 引数チェック
+	if (name == NULL || (data == NULL && size != 0))
+	{
+		return false;
+	}
+
+	io = FileCreateW(name);
+
+	if (io == NULL)
+	{
+		return false;
+	}
+
+	FileWrite(io, data, size);
+
+	FileClose(io);
+
+	return true;
+}
+
+// ファイルを開く
+IO *FileOpenInner(char *name, bool write_mode, bool read_lock)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	IO *ret = FileOpenInnerW(name_w, write_mode, read_lock);
+
+	Free(name_w);
+
+	return ret;
+}
+IO *FileOpenInnerW(wchar_t *name, bool write_mode, bool read_lock)
+{
+	IO *o;
+	void *p;
+	wchar_t name2[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	UniStrCpy(name2, sizeof(name2), name);
+	ConvertPathW(name2);
+
+	p = OSFileOpenW(name2, write_mode, read_lock);
+	if (p == NULL)
+	{
+		return NULL;
+	}
+
+	o = ZeroMalloc(sizeof(IO));
+	o->pData = p;
+	UniStrCpy(o->NameW, sizeof(o->NameW), name2);
+	UniToStr(o->Name, sizeof(o->Name), o->NameW);
+	o->WriteMode = write_mode;
+
+	// KS
+	KS_INC(KS_IO_OPEN_COUNT);
+
+	return o;
+}
+IO *FileOpen(char *name, bool write_mode)
+{
+	return FileOpenEx(name, write_mode, true);
+}
+IO *FileOpenW(wchar_t *name, bool write_mode)
+{
+	return FileOpenExW(name, write_mode, true);
+}
+IO *FileOpenEx(char *name, bool write_mode, bool read_lock)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+	IO *ret = FileOpenExW(name_w, write_mode, read_lock);
+
+	Free(name_w);
+
+	return ret;
+}
+IO *FileOpenExW(wchar_t *name, bool write_mode, bool read_lock)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	InnerFilePathW(tmp, sizeof(tmp), name);
+
+	if (name[0] == L'|')
+	{
+		IO *o = ZeroMalloc(sizeof(IO));
+		name++;
+		UniStrCpy(o->NameW, sizeof(o->NameW), name);
+		UniToStr(o->Name, sizeof(o->Name), o->NameW);
+		o->HamMode = true;
+		o->HamBuf = ReadHamcoreW(name);
+		if (o->HamBuf == NULL)
+		{
+			Free(o);
+			return NULL;
+		}
+		return o;
+	}
+	else
+	{
+		return FileOpenInnerW(tmp, write_mode, read_lock);
+	}
+}
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/FileIO.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/FileIO.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/FileIO.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,235 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// FileIO.h
+// FileIO.c のヘッダ
+
+#ifndef	FILEIO_H
+#define	FILEIO_H
+
+// 定数
+#define	HAMCORE_DIR_NAME			"hamcore"
+#define	HAMCORE_FILE_NAME			"hamcore.utvpn"
+#define	HAMCORE_FILE_NAME_2			"_hamcore.utvpn"
+#define	HAMCORE_TEXT_NAME			"hamcore.txt"
+#define	HAMCORE_HEADER_DATA			"HamCore"
+#define	HAMCORE_HEADER_SIZE			7
+#define	HAMCORE_CACHE_EXPIRES		(5 * 60 * 1000)
+
+// IO 構造体
+struct IO
+{
+	char Name[MAX_SIZE];
+	wchar_t NameW[MAX_SIZE];
+	void *pData;
+	bool WriteMode;
+	bool HamMode;
+	BUF *HamBuf;
+};
+
+// HC 構造体
+typedef struct HC
+{
+	char *FileName;				// ファイル名
+	UINT Size;					// ファイルサイズ
+	UINT SizeCompressed;		// 圧縮されたファイルサイズ
+	UINT Offset;				// オフセット
+	void *Buffer;				// バッファ
+	UINT64 LastAccess;			// 最後にアクセスした日時
+} HC;
+
+// DIRENT 構造体
+struct DIRENT
+{
+	bool Folder;				// フォルダ
+	char *FileName;				// ファイル名 (ANSI)
+	wchar_t *FileNameW;			// ファイル名 (Unicode)
+	UINT64 FileSize;			// ファイルサイズ
+	UINT64 CreateDate;			// 作成日時
+	UINT64 UpdateDate;			// 更新日時
+};
+
+// DIRLIST 構造体
+struct DIRLIST
+{
+	UINT NumFiles;				// ファイル数
+	struct DIRENT **File;			// ファイル配列
+};
+
+bool DeleteDirInner(char *name);
+bool DeleteDirInnerW(wchar_t *name);
+bool DeleteDir(char *name);
+bool DeleteDirW(wchar_t *name);
+bool MakeDirInner(char *name);
+bool MakeDirInnerW(wchar_t *name);
+bool MakeDir(char *name);
+bool MakeDirW(wchar_t *name);
+void MakeDirEx(char *name);
+void MakeDirExW(wchar_t *name);
+bool FileDeleteInner(char *name);
+bool FileDeleteInnerW(wchar_t *name);
+bool FileDelete(char *name);
+bool FileDeleteW(wchar_t *name);
+bool FileSeek(IO *o, UINT mode, int offset);
+UINT FileSize(IO *o);
+UINT64 FileSize64(IO *o);
+UINT FileSizeEx(char *name);
+UINT FileSizeExW(wchar_t *name);
+UINT FileRead(IO *o, void *buf, UINT size);
+UINT FileWrite(IO *o, void *buf, UINT size);
+void FileFlush(IO *o);
+void FileClose(IO *o);
+void FileCloseEx(IO *o, bool no_flush);
+void FileCloseAndDelete(IO *o);
+IO *FileCreateInner(char *name);
+IO *FileCreateInnerW(wchar_t *name);
+IO *FileCreate(char *name);
+IO *FileCreateW(wchar_t *name);
+bool FileWriteAll(char *name, void *data, UINT size);
+bool FileWriteAllW(wchar_t *name, void *data, UINT size);
+IO *FileOpenInner(char *name, bool write_mode, bool read_lock);
+IO *FileOpenInnerW(wchar_t *name, bool write_mode, bool read_lock);
+IO *FileOpen(char *name, bool write_mode);
+IO *FileOpenW(wchar_t *name, bool write_mode);
+IO *FileOpenEx(char *name, bool write_mode, bool read_lock);
+IO *FileOpenExW(wchar_t *name, bool write_mode, bool read_lock);
+void ConvertPath(char *path);
+void ConvertPathW(wchar_t *path);
+bool FileRenameInner(char *old_name, char *new_name);
+bool FileRenameInnerW(wchar_t *old_name, wchar_t *new_name);
+bool FileRename(char *old_name, char *new_name);
+bool FileRenameW(wchar_t *old_name, wchar_t *new_name);
+void NormalizePath(char *dst, UINT size, char *src);
+void NormalizePathW(wchar_t *dst, UINT size, wchar_t *src);
+TOKEN_LIST *ParseSplitedPath(char *path);
+UNI_TOKEN_LIST *ParseSplitedPathW(wchar_t *path);
+char *GetCurrentPathEnvStr();
+bool IsFileExistsInner(char *name);
+bool IsFileExistsInnerW(wchar_t *name);
+bool IsFileExists(char *name);
+bool IsFileExistsW(wchar_t *name);
+void InnerFilePath(char *dst, UINT size, char *src);
+void InnerFilePathW(wchar_t *dst, UINT size, wchar_t *src);
+void ConbinePath(char *dst, UINT size, char *dirname, char *filename);
+void ConbinePathW(wchar_t *dst, UINT size, wchar_t *dirname, wchar_t *filename);
+void CombinePath(char *dst, UINT size, char *dirname, char *filename);
+void CombinePathW(wchar_t *dst, UINT size, wchar_t *dirname, wchar_t *filename);
+void GetDirNameFromFilePath(char *dst, UINT size, char *filepath);
+void GetDirNameFromFilePathW(wchar_t *dst, UINT size, wchar_t *filepath);
+void GetFileNameFromFilePath(char *dst, UINT size, char *filepath);
+void GetFileNameFromFilePathW(wchar_t *dst, UINT size, wchar_t *filepath);
+void MakeSafeFileName(char *dst, UINT size, char *src);
+void MakeSafeFileNameW(wchar_t *dst, UINT size, wchar_t *src);
+void InitGetExeName(char *arg);
+void UnixGetExeNameW(wchar_t *name, UINT size, wchar_t *arg);
+void GetExeName(char *name, UINT size);
+void GetExeNameW(wchar_t *name, UINT size);
+void GetExeDir(char *name, UINT size);
+void GetExeDirW(wchar_t *name, UINT size);
+void BuildHamcore();
+int CompareHamcore(void *p1, void *p2);
+void InitHamcore();
+void FreeHamcore();
+BUF *ReadHamcore(char *name);
+BUF *ReadHamcoreW(wchar_t *filename);
+void SafeFileName(char *name);
+void SafeFileNameW(wchar_t *name);
+void UniSafeFileName(wchar_t *name);
+DIRLIST *EnumDir(char *dirname);
+DIRLIST *EnumDirW(wchar_t *dirname);
+DIRLIST *EnumDirEx(char *dirname, COMPARE *compare);
+DIRLIST *EnumDirExW(wchar_t *dirname, COMPARE *compare);
+void FreeDir(DIRLIST *d);
+int CompareDirListByName(void *p1, void *p2);
+bool GetDiskFree(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size);
+bool GetDiskFreeW(wchar_t *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size);
+void ConvertSafeFileName(char *dst, UINT size, char *src);
+void ConvertSafeFileNameW(wchar_t *dst, UINT size, wchar_t *src);
+bool FileReplaceRename(char *old_name, char *new_name);
+bool FileReplaceRenameW(wchar_t *old_name, wchar_t *new_name);
+bool IsFile(char *name);
+bool IsFileW(wchar_t *name);
+void GetCurrentDirW(wchar_t *name, UINT size);
+void GetCurrentDir(char *name, UINT size);
+bool SaveFileW(wchar_t *name, void *data, UINT size);
+bool SaveFile(char *name, void *data, UINT size);
+
+
+#endif	// FILEIO_H
+
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Internat.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Internat.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Internat.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,3396 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Internat.c
+// 国際化のための文字列変換ライブラリ
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+extern LOCK *token_lock;
+static char charset[MAX_SIZE] = "EUCJP";
+static LOCK *iconv_lock = NULL;
+void *iconv_cache_wide_to_str = 0;
+void *iconv_cache_str_to_wide = 0;
+
+// 文字列が含まれているかどうかチェック
+bool UniInStr(wchar_t *str, wchar_t *keyword)
+{
+	return UniInStrEx(str, keyword, false);
+}
+bool UniInStrEx(wchar_t *str, wchar_t *keyword, bool case_sensitive)
+{
+	// 引数チェック
+	if (UniIsEmptyStr(str) || UniIsEmptyStr(keyword))
+	{
+		return false;
+	}
+
+	if (UniSearchStrEx(str, keyword, 0, case_sensitive) == INFINITE)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// バイナリデータに変換
+BUF *UniStrToBin(wchar_t *str)
+{
+	char *str_a = CopyUniToStr(str);
+	BUF *ret;
+
+	ret = StrToBin(str_a);
+
+	Free(str_a);
+
+	return ret;
+}
+
+// 指定した文字の列を生成する
+wchar_t *UniMakeCharArray(wchar_t c, UINT count)
+{
+	UINT i;
+	wchar_t *ret = Malloc(sizeof(wchar_t) * (count + 1));
+
+	for (i = 0;i < count;i++)
+	{
+		ret[i] = c;
+	}
+
+	ret[count] = 0;
+
+	return ret;
+}
+
+// 安全な文字かどうかチェック
+bool UniIsSafeChar(wchar_t c)
+{
+	UINT i, len;
+	wchar_t *check_str =
+		L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+		L"abcdefghijklmnopqrstuvwxyz"
+		L"0123456789"
+		L" ()-_#%&.";
+
+	len = UniStrLen(check_str);
+	for (i = 0;i < len;i++)
+	{
+		if (c == check_str[i])
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
+// トークンリストを文字列リストに変換する
+LIST *UniTokenListToList(UNI_TOKEN_LIST *t)
+{
+	UINT i;
+	LIST *o;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return NULL;
+	}
+
+	o = NewListFast(NULL);
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		Insert(o, UniCopyStr(t->Token[i]));
+	}
+
+	return o;
+}
+
+// 文字列リストをトークンリストに変換する
+UNI_TOKEN_LIST *UniListToTokenList(LIST *o)
+{
+	UINT i;
+	UNI_TOKEN_LIST *t;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	t = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
+	t->NumTokens = LIST_NUM(o);
+	t->Token = ZeroMalloc(sizeof(wchar_t *) * t->NumTokens);
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		t->Token[i] = UniCopyStr(LIST_DATA(o, i));
+	}
+
+	return t;
+}
+
+// 文字列リストを解放する
+void UniFreeStrList(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		wchar_t *s = LIST_DATA(o, i);
+		Free(s);
+	}
+
+	ReleaseList(o);
+}
+
+// 文字列リストを文字列に変換する
+BUF *UniStrListToStr(LIST *o)
+{
+	BUF *b;
+	UINT i;
+	wchar_t c;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+	b = NewBuf();
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		wchar_t *s = LIST_DATA(o, i);
+		WriteBuf(b, s, UniStrSize(s));
+	}
+
+	c = 0;
+	WriteBuf(b, &c, sizeof(c));
+
+	SeekBuf(b, 0, 0);
+
+	return b;
+}
+
+// 文字列 (NULL区切り) をリストに変換する
+LIST *UniStrToStrList(wchar_t *str, UINT size)
+{
+	LIST *o;
+	wchar_t *tmp;
+	UINT tmp_size;
+	UINT i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	o = NewListFast(NULL);
+
+	i = 0;
+	while (true)
+	{
+		if (i >= size)
+		{
+			break;
+		}
+		if (*str == 0)
+		{
+			break;
+		}
+
+		tmp_size = UniStrSize(str);
+		tmp = ZeroMalloc(tmp_size);
+		UniStrCpy(tmp, tmp_size, str);
+		Add(o, tmp);
+		str += UniStrLen(str) + 1;
+		i++;
+	}
+
+	return o;
+}
+
+// 改行コードを正規化する
+wchar_t *UniNormalizeCrlf(wchar_t *str)
+{
+	wchar_t *ret;
+	UINT ret_size, i, len, wp;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	len = UniStrLen(str);
+	ret_size = sizeof(wchar_t) * (len + 32) * 2;
+	ret = Malloc(ret_size);
+
+	wp = 0;
+
+	for (i = 0;i < len;i++)
+	{
+		wchar_t c = str[i];
+
+		switch (c)
+		{
+		case L'\r':
+			if (str[i + 1] == L'\n')
+			{
+				i++;
+			}
+			ret[wp++] = L'\r';
+			ret[wp++] = L'\n';
+			break;
+
+		case L'\n':
+			ret[wp++] = L'\r';
+			ret[wp++] = L'\n';
+			break;
+
+		default:
+			ret[wp++] = c;
+			break;
+		}
+	}
+
+	ret[wp++] = 0;
+
+	return ret;
+}
+
+// str が key で終了するかどうかチェック
+bool UniEndWith(wchar_t *str, wchar_t *key)
+{
+	UINT str_len;
+	UINT key_len;
+	// 引数チェック
+	if (str == NULL || key == NULL)
+	{
+		return false;
+	}
+
+	// 比較
+	str_len = UniStrLen(str);
+	key_len = UniStrLen(key);
+	if (str_len < key_len)
+	{
+		return false;
+	}
+
+	if (UniStrCmpi(str + (str_len - key_len), key) == 0)
+	{
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+// str が key で始まるかどうかチェック
+bool UniStartWith(wchar_t *str, wchar_t *key)
+{
+	UINT str_len;
+	UINT key_len;
+	wchar_t *tmp;
+	bool ret;
+	// 引数チェック
+	if (str == NULL || key == NULL)
+	{
+		return false;
+	}
+
+	// 比較
+	str_len = UniStrLen(str);
+	key_len = UniStrLen(key);
+	if (str_len < key_len)
+	{
+		return false;
+	}
+	if (str_len == 0 || key_len == 0)
+	{
+		return false;
+	}
+	tmp = CopyUniStr(str);
+	tmp[key_len] = 0;
+
+	if (UniStrCmpi(tmp, key) == 0)
+	{
+		ret = true;
+	}
+	else
+	{
+		ret = false;
+	}
+
+	Free(tmp);
+
+	return ret;
+}
+
+// 整数をカンマ区切り文字列に変換する
+void UniToStr3(wchar_t *str, UINT size, UINT64 value)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	ToStr3(tmp, sizeof(tmp), value);
+
+	StrToUni(str, size, tmp);
+}
+
+// 文字列のフォーマット (内部関数)
+wchar_t *InternalFormatArgs(wchar_t *fmt, va_list args, bool ansi_mode)
+{
+	UINT i, len;
+	wchar_t *tmp;
+	UINT tmp_size;
+	LIST *o;
+	UINT mode = 0;
+	UINT wp;
+	UINT total_size;
+	wchar_t *ret;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return NULL;
+	}
+
+	len = UniStrLen(fmt);
+	tmp_size = UniStrSize(fmt);
+	tmp = Malloc(tmp_size);
+
+	o = NewListFast(NULL);
+
+	mode = 0;
+
+	wp = 0;
+
+	for (i = 0;i < len;i++)
+	{
+		wchar_t c = fmt[i];
+
+		if (mode == 0)
+		{
+			// 通常の文字モード
+			switch (c)
+			{
+			case L'%':
+				// 書式指定の開始
+				if (fmt[i + 1] == L'%')
+				{
+					// 次の文字も % の場合は % を一文字出力するだけ
+					i++;
+					tmp[wp++] = c;
+				}
+				else
+				{
+					// 次の文字が % でない場合は状態遷移を行う
+					mode = 1;
+					tmp[wp++] = 0;
+					wp = 0;
+					Add(o, CopyUniStr(tmp));
+					tmp[wp++] = c;
+				}
+				break;
+			default:
+				// 通常の文字
+				tmp[wp++] = c;
+				break;
+			}
+		}
+		else
+		{
+			char *tag;
+			char dst[MAX_SIZE];
+			wchar_t *target_str;
+			wchar_t *padding_str;
+			bool left_padding;
+			UINT target_str_len;
+			UINT total_len;
+			wchar_t *output_str;
+			UINT padding;
+			// 書式指定モード
+			switch (c)
+			{
+			case L'c':
+			case L'C':
+			case L'd':
+			case L'i':
+			case L'o':
+			case L'u':
+			case L'x':
+			case L'X':
+				// int 型
+				tmp[wp++] = c;
+				tmp[wp++] = 0;
+				tag = CopyUniToStr(tmp);
+
+				#ifdef	OS_WIN32
+					ReplaceStrEx(tag, 0, tag, "ll", "I64", false);
+				#else	// OS_WIN32
+					ReplaceStrEx(tag, 0, tag, "I64", "ll", false);
+				#endif	// OS_WIN32
+
+				if ((UniStrLen(tmp) >= 5 && tmp[UniStrLen(tmp) - 4] == L'I' &&
+					tmp[UniStrLen(tmp) - 3] == L'6' &&
+					tmp[UniStrLen(tmp) - 2] == L'4') ||
+					(
+					UniStrLen(tmp) >= 4 && tmp[UniStrLen(tmp) - 3] == L'l' &&
+					tmp[UniStrLen(tmp) - 2] == L'l'))
+				{
+					#ifdef	OS_WIN32
+						_snprintf(dst, sizeof(dst), tag, va_arg(args, UINT64));
+					#else	// OS_WIN32
+						snprintf(dst, sizeof(dst), tag, va_arg(args, UINT64));
+					#endif	// OS_WIN32
+				}
+				else
+				{
+					#ifdef	OS_WIN32
+						_snprintf(dst, sizeof(dst), tag, va_arg(args, int));
+					#else	// OS_WIN32
+						snprintf(dst, sizeof(dst), tag, va_arg(args, int));
+					#endif	// OS_WIN32
+				}
+
+				Free(tag);
+				Add(o, CopyStrToUni(dst));
+
+				wp = 0;
+				mode = 0;
+				break;
+			case L'e':
+			case L'E':
+			case L'f':
+			case L'g':
+			case L'G':
+				// double 型
+				tmp[wp++] = c;
+				tmp[wp++] = 0;
+				tag = CopyUniToStr(tmp);
+
+				#ifdef	OS_WIN32
+					_snprintf(dst, sizeof(dst), tag, va_arg(args, double));
+				#else	// OS_WIN32
+					snprintf(dst, sizeof(dst), tag, va_arg(args, double));
+				#endif	// OS_WIN32
+
+				Free(tag);
+				Add(o, CopyStrToUni(dst));
+
+				wp = 0;
+				mode = 0;
+				break;
+			case L'n':
+			case L'p':
+				// ポインタ型
+				tmp[wp++] = c;
+				tmp[wp++] = 0;
+				tag = ZeroMalloc(UniStrSize(tmp) + 32);
+				UniToStr(tag, 0, tmp);
+
+				#ifdef	OS_WIN32
+					_snprintf(dst, sizeof(dst), tag, va_arg(args, void *));
+				#else	// OS_WIN32
+					snprintf(dst, sizeof(dst), tag, va_arg(args, void *));
+				#endif	// OS_WIN32
+
+				Free(tag);
+				Add(o, CopyStrToUni(dst));
+
+				wp = 0;
+				mode = 0;
+				break;
+			case L's':
+			case L'S':
+				// 文字列型
+				tmp[wp++] = c;
+				tmp[wp++] = 0;
+
+				if (ansi_mode == false)
+				{
+					if (c == L'S')
+					{
+						c = L's';
+					}
+					else
+					{
+						c = L'S';
+					}
+				}
+
+				if (c == L's')
+				{
+					target_str = CopyStrToUni(va_arg(args, char *));
+				}
+				else
+				{
+					target_str = CopyUniStr(va_arg(args, wchar_t *));
+				}
+
+				if (target_str == NULL)
+				{
+					target_str = CopyUniStr(L"(null)");
+				}
+
+				padding = 0;
+				left_padding = false;
+				if (tmp[1] == L'-')
+				{
+					// 左詰め
+					if (UniStrLen(tmp) >= 3)
+					{
+						padding = UniToInt(&tmp[2]);
+					}
+					left_padding = true;
+				}
+				else
+				{
+					// 右詰め
+					if (UniStrLen(tmp) >= 2)
+					{
+						padding = UniToInt(&tmp[1]);
+					}
+				}
+
+				target_str_len = UniStrWidth(target_str);
+
+				if (padding > target_str_len)
+				{
+					UINT len = padding - target_str_len;
+					UINT i;
+					padding_str = ZeroMalloc(sizeof(wchar_t) * (len + 1));
+					for (i = 0;i < len;i++)
+					{
+						padding_str[i] = L' ';
+					}
+				}
+				else
+				{
+					padding_str = ZeroMalloc(sizeof(wchar_t));
+				}
+
+				total_len = sizeof(wchar_t) * (UniStrLen(padding_str) + UniStrLen(target_str) + 1);
+				output_str = ZeroMalloc(total_len);
+				output_str[0] = 0;
+
+				if (left_padding == false)
+				{
+					UniStrCat(output_str, total_len, padding_str);
+				}
+				UniStrCat(output_str, total_len, target_str);
+				if (left_padding)
+				{
+					UniStrCat(output_str, total_len, padding_str);
+				}
+
+				Add(o, output_str);
+
+				Free(target_str);
+				Free(padding_str);
+
+				wp = 0;
+				mode = 0;
+				break;
+			default:
+				// 通常の文字列
+				tmp[wp++] = c;
+				break;
+			}
+		}
+	}
+	tmp[wp++] = 0;
+	wp = 0;
+
+	if (UniStrLen(tmp) >= 1)
+	{
+		Add(o, CopyUniStr(tmp));
+	}
+
+	total_size = sizeof(wchar_t);
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		wchar_t *s = LIST_DATA(o, i);
+		total_size += UniStrLen(s) * sizeof(wchar_t);
+	}
+
+	ret = ZeroMalloc(total_size);
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		wchar_t *s = LIST_DATA(o, i);
+		UniStrCat(ret, total_size, s);
+		Free(s);
+	}
+
+	ReleaseList(o);
+
+	Free(tmp);
+
+	return ret;
+}
+
+// 文字列の横幅サイズを取得する
+UINT UniStrWidth(wchar_t *str)
+{
+	UINT i, len, ret;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	ret = 0;
+	len = UniStrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		if (str[i] <= 255)
+		{
+			ret++;
+		}
+		else
+		{
+			ret += 2;
+		}
+	}
+	return ret;
+}
+
+// Unicode 文字列をダンプ表示する
+void DumpUniStr(wchar_t *str)
+{
+	UINT i, len;
+	char *s;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	s = CopyUniToStr(str);
+
+	Print("DumpUniStr: %s\n  ", s);
+
+	len = UniStrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		Print("0x%04X ", str[i]);
+	}
+	Print("\n");
+
+	Free(s);
+}
+
+// 文字列をダンプ表示する
+void DumpStr(char *str)
+{
+	UINT i, len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	Print("DumpStr: %s\n  ", str);
+
+	len = StrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		Print("0x%02X ", str[i]);
+	}
+	Print("\n");
+}
+
+// 1 文字 2 バイトの文字列を 1 文字 4 場合の wchar_t に変換する
+wchar_t *Utf16ToWide(USHORT *str)
+{
+	wchar_t *ret;
+	UINT len, i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	len = 0;
+	while (true)
+	{
+		if (str[len] == 0)
+		{
+			break;
+		}
+		len++;
+	}
+
+	ret = Malloc((len + 1) * sizeof(wchar_t));
+	for (i = 0;i < len + 1;i++)
+	{
+		ret[i] = (wchar_t)str[i];
+	}
+
+	return ret;
+}
+
+// 1 文字 4 バイトの wchar_t 文字列を 1 文字 2 バイトに変換する
+USHORT *WideToUtf16(wchar_t *str)
+{
+	USHORT *ret;
+	UINT len;
+	UINT ret_size;
+	UINT i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	len = UniStrLen(str);
+
+	ret_size = (len + 1) * 2;
+	ret = Malloc(ret_size);
+
+	for (i = 0;i < len + 1;i++)
+	{
+		ret[i] = (USHORT)str[i];
+	}
+
+	return ret;
+}
+
+// 国際ライブラリの初期化
+void InitInternational()
+{
+#ifdef	OS_UNIX
+	void *d;
+
+	if (iconv_lock != NULL)
+	{
+		return;
+	}
+
+	GetCurrentCharSet(charset, sizeof(charset));
+	d = IconvWideToStrInternal();
+	if (d == (void *)-1)
+	{
+#ifdef	UNIX_MACOS
+		StrCpy(charset, sizeof(charset), "utf8");
+#else	// UNIX_MACOS
+		StrCpy(charset, sizeof(charset), "EUCJP");
+#endif	// UNIX_MACOS
+		d = IconvWideToStrInternal();
+		if (d == (void *)-1)
+		{
+			StrCpy(charset, sizeof(charset), "US");
+		}
+		else
+		{
+			IconvFreeInternal(d);
+		}
+	}
+	else
+	{
+		IconvFreeInternal(d);
+	}
+
+	iconv_lock = NewLockMain();
+
+	iconv_cache_wide_to_str = IconvWideToStrInternal();
+	iconv_cache_str_to_wide = IconvStrToWideInternal();
+#endif	// OS_UNIX
+}
+
+// 国際ライブラリの解放
+void FreeInternational()
+{
+#ifdef	OS_UNIX
+#endif	// OS_UNIX
+}
+
+#ifdef	OS_UNIX
+
+// 文字列を Unicode に変換した場合のサイズを計算する
+UINT UnixCalcStrToUni(char *str)
+{
+	wchar_t *tmp;
+	UINT len, tmp_size;
+	UINT ret;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	len = StrLen(str);
+	tmp_size = len * 5 + 10;
+	tmp = ZeroMalloc(tmp_size);
+	UnixStrToUni(tmp, tmp_size, str);
+	ret = UniStrLen(tmp);
+	Free(tmp);
+
+	return (ret + 1) * sizeof(wchar_t);
+}
+
+// 文字列を Unicode に変換する
+UINT UnixStrToUni(wchar_t *s, UINT size, char *str)
+{
+	void *d;
+	char *inbuf;
+	size_t insize;
+	char *outbuf;
+	char *outbuf_orig;
+	size_t outsize;
+	wchar_t *tmp;
+	// 引数チェック
+	if (s == NULL || str == NULL)
+	{
+		return 0;
+	}
+
+	d = IconvStrToWide();
+	if (d == (void *)-1)
+	{
+		UniStrCpy(s, size, L"");
+		return 0;
+	}
+
+	inbuf = (char *)str;
+	insize = StrLen(str) + 1;
+	outsize = insize * 5 + 10;
+	outbuf_orig = outbuf = ZeroMalloc(outsize);
+
+	if (iconv((iconv_t)d, (char **)&inbuf, (size_t *)&insize, (char **)&outbuf, (size_t *)&outsize) == (size_t)(-1))
+	{
+		Free(outbuf_orig);
+		UniStrCpy(s, size, L"");
+		IconvFree(d);
+		return 0;
+	}
+
+	tmp = Utf16ToWide((USHORT *)outbuf_orig);
+	Free(outbuf_orig);
+
+	UniStrCpy(s, size, tmp);
+	IconvFree(d);
+
+	Free(tmp);
+
+	return UniStrLen(s);
+}
+
+// Unicode を文字列にした場合のサイズを計算する
+UINT UnixCalcUniToStr(wchar_t *s)
+{
+	char *tmp;
+	UINT tmp_size;
+	UINT ret;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return 0;
+	}
+
+	tmp_size = UniStrLen(s) * 5 + 10;
+	tmp = ZeroMalloc(tmp_size);
+	UnixUniToStr(tmp, tmp_size, s);
+
+	ret = StrSize(tmp);
+	Free(tmp);
+
+	return ret;
+}
+
+// Unicode を文字列に変換する
+UINT UnixUniToStr(char *str, UINT size, wchar_t *s)
+{
+	USHORT *tmp;
+	char *inbuf;
+	size_t insize;
+	char *outbuf;
+	char *outbuf_orig;
+	size_t outsize;
+	void *d;
+	// 引数チェック
+	if (str == NULL || s == NULL)
+	{
+		return 0;
+	}
+
+	// まず wchar_t 文字列を 2 バイトの並びに変換する
+	tmp = WideToUtf16(s);
+	inbuf = (char *)tmp;
+	insize = (UniStrLen(s) + 1) * 2;
+	outsize = insize * 5 + 10;
+	outbuf_orig = outbuf = ZeroMalloc(outsize);
+
+	d = IconvWideToStr();
+	if (d == (void *)-1)
+	{
+		StrCpy(str, size, "");
+		Free(outbuf);
+		Free(tmp);
+		return 0;
+	}
+
+	if (iconv((iconv_t)d, (char **)&inbuf, (size_t *)&insize, (char **)&outbuf, (size_t *)&outsize) == (size_t)(-1))
+	{
+		Free(outbuf_orig);
+		IconvFree(d);
+		StrCpy(str, size, "");
+		Free(tmp);
+		return 0;
+	}
+
+	StrCpy(str, size, outbuf_orig);
+
+	Free(outbuf_orig);
+	IconvFree(d);
+	Free(tmp);
+
+	return StrLen(str);
+}
+
+// whcar_t を char に変換する
+void *IconvWideToStrInternal()
+{
+	return (void *)iconv_open(charset, IsBigEndian() ? "UTF-16BE" : "UTF-16LE");
+}
+
+// char を wchar_t に変換する
+void *IconvStrToWideInternal()
+{
+	return (void *)iconv_open(IsBigEndian() ? "UTF-16BE" : "UTF-16LE", charset);
+}
+
+// ハンドルを閉じる
+int IconvFreeInternal(void *d)
+{
+	iconv_close((iconv_t)d);
+	return 0;
+}
+
+void *IconvWideToStr()
+{
+	if (iconv_cache_wide_to_str == (void *)-1)
+	{
+		return (void *)-1;
+	}
+
+	Lock(iconv_lock);
+
+	return iconv_cache_wide_to_str;
+}
+
+void *IconvStrToWide()
+{
+	if (iconv_cache_str_to_wide == (void *)-1)
+	{
+		return (void *)-1;
+	}
+
+	Lock(iconv_lock);
+
+	return iconv_cache_str_to_wide;
+}
+
+int IconvFree(void *d)
+{
+	Unlock(iconv_lock);
+
+	return 0;
+}
+
+// 現在使用されている文字セットを環境変数から取得する
+void GetCurrentCharSet(char *name, UINT size)
+{
+	char tmp[MAX_SIZE];
+	TOKEN_LIST *t;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	if (GetEnv("LANG", tmp, sizeof(tmp)) == false)
+	{
+		if (GetEnv("LOCATION", tmp, sizeof(tmp)) == false)
+		{
+			StrCpy(tmp, sizeof(tmp), "ja_JP.eucJP");
+		}
+	}
+
+	Trim(tmp);
+
+	t = ParseToken(tmp, ".");
+	if (t->NumTokens >= 2)
+	{
+		StrCpy(name, size, t->Token[1]);
+	}
+	else
+	{
+		if (t->NumTokens == 1)
+		{
+			StrCpy(name, size, t->Token[0]);
+		}
+		else
+		{
+			StrCpy(name, size, "eucJP");
+		}
+	}
+	FreeToken(t);
+
+	StrUpper(name);
+}
+
+#endif	// OS_UNIX
+
+// 指定された文字列が空白かどうかチェック
+bool UniIsEmptyStr(wchar_t *str)
+{
+	return IsEmptyUniStr(str);
+}
+bool IsEmptyUniStr(wchar_t *str)
+{
+	bool ret;
+	wchar_t *s;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return true;
+	}
+
+	s = UniCopyStr(str);
+
+	UniTrim(s);
+	if (UniStrLen(s) == 0)
+	{
+		ret = true;
+	}
+	else
+	{
+		ret = false;
+	}
+
+	Free(s);
+
+	return ret;
+}
+
+// 指定された文字列が数字かどうかチェック
+bool UniIsNum(wchar_t *str)
+{
+	char tmp[MAX_SIZE];
+
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	UniToStr(tmp, sizeof(tmp), str);
+
+	return IsNum(tmp);
+}
+
+
+// 中身が無い Unicode トークンリスト
+UNI_TOKEN_LIST *UniNullToken()
+{
+	UNI_TOKEN_LIST *ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
+	ret->Token = ZeroMalloc(0);
+
+	return ret;
+}
+
+// 中身が無い Unicode トークンリスト (別名)
+UNI_TOKEN_LIST *NullUniToken()
+{
+	return UniNullToken();
+}
+
+// トークンリストを Unicode トークンリストに変換する
+UNI_TOKEN_LIST *TokenListToUniTokenList(TOKEN_LIST *src)
+{
+	UNI_TOKEN_LIST *ret;
+	UINT i;
+	// 引数チェック
+	if (src == NULL)
+	{
+		return NULL;
+	}
+
+	ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
+	ret->NumTokens = src->NumTokens;
+	ret->Token = ZeroMalloc(sizeof(wchar_t *) * ret->NumTokens);
+
+	for (i = 0;i < ret->NumTokens;i++)
+	{
+		ret->Token[i] = CopyStrToUni(src->Token[i]);
+	}
+
+	return ret;
+}
+
+// Unicode トークンリストをトークンリストに変換する
+TOKEN_LIST *UniTokenListToTokenList(UNI_TOKEN_LIST *src)
+{
+	TOKEN_LIST *ret;
+	UINT i;
+	// 引数チェック
+	if (src == NULL)
+	{
+		return NULL;
+	}
+
+	ret = ZeroMalloc(sizeof(TOKEN_LIST));
+	ret->NumTokens = src->NumTokens;
+	ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
+
+	for (i = 0;i < ret->NumTokens;i++)
+	{
+		ret->Token[i] = CopyUniToStr(src->Token[i]);
+	}
+
+	return ret;
+}
+
+// Unicode 文字列コピー
+wchar_t *UniCopyStr(wchar_t *str)
+{
+	return CopyUniStr(str);
+}
+
+// トークンリストのコピー
+UNI_TOKEN_LIST *UniCopyToken(UNI_TOKEN_LIST *src)
+{
+	UNI_TOKEN_LIST *ret;
+	UINT i;
+	// 引数チェック
+	if (src == NULL)
+	{
+		return NULL;
+	}
+
+	ret = ZeroMalloc(sizeof(TOKEN_LIST));
+	ret->NumTokens = src->NumTokens;
+	ret->Token = ZeroMalloc(sizeof(wchar_t *) * ret->NumTokens);
+	for (i = 0;i < ret->NumTokens;i++)
+	{
+		ret->Token[i] = CopyUniStr(src->Token[i]);
+	}
+
+	return ret;
+}
+
+// コマンドライン文字列をパースする
+UNI_TOKEN_LIST *UniParseCmdLine(wchar_t *str)
+{
+	UNI_TOKEN_LIST *t;
+	LIST *o;
+	UINT i, len, wp, mode;
+	wchar_t c;
+	wchar_t *tmp;
+	bool ignore_space = false;
+	// 引数チェック
+	if (str == NULL)
+	{
+		// トークン無し
+		return UniNullToken();
+	}
+
+	o = NewListFast(NULL);
+	tmp = Malloc(UniStrSize(str) + 32);
+
+	wp = 0;
+	mode = 0;
+
+	len = UniStrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		c = str[i];
+
+		switch (mode)
+		{
+		case 0:
+			// 次のトークンを発見するモード
+			if (c == L' ' || c == L'\t')
+			{
+				// 次の文字へ進める
+			}
+			else
+			{
+				// トークンの開始
+				if (c == L'\"')
+				{
+					if (str[i + 1] == L'\"')
+					{
+						// 2 重の " は 1 個の " 文字として見なす
+						tmp[wp++] = L'\"';
+						i++;
+					}
+					else
+					{
+						// 1 個の " はスペース無視フラグを有効にする
+						ignore_space = true;
+					}
+				}
+				else
+				{
+					tmp[wp++] = c;
+				}
+
+				mode = 1;
+			}
+			break;
+
+		case 1:
+			if (ignore_space == false && (c == L' ' || c == L'\t'))
+			{
+				// トークンの終了
+				tmp[wp++] = 0;
+				wp = 0;
+
+				Insert(o, UniCopyStr(tmp));
+				mode = 0;
+			}
+			else
+			{
+				if (c == L'\"')
+				{
+					if (str[i + 1] == L'\"')
+					{
+						// 2 重の " は 1 個の " 文字として見なす
+						tmp[wp++] = L'\"';
+						i++;
+					}
+					else
+					{
+						if (ignore_space == false)
+						{
+							// 1 個の " はスペース無視フラグを有効にする
+							ignore_space = true;
+						}
+						else
+						{
+							// スペース無視フラグを無効にする
+							ignore_space = false;
+						}
+					}
+				}
+				else
+				{
+					tmp[wp++] = c;
+				}
+			}
+			break;
+		}
+	}
+
+	if (wp != 0)
+	{
+		tmp[wp++] = 0;
+		Insert(o, UniCopyStr(tmp));
+	}
+
+	Free(tmp);
+
+	t = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
+	t->NumTokens = LIST_NUM(o);
+	t->Token = ZeroMalloc(sizeof(wchar_t *) * t->NumTokens);
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		t->Token[i] = LIST_DATA(o, i);
+	}
+
+	ReleaseList(o);
+
+	return t;
+}
+
+// Unicode 文字列を 64bit 整数に変換する
+UINT64 UniToInt64(wchar_t *str)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	UniToStr(tmp, sizeof(tmp), str);
+
+	return ToInt64(tmp);
+}
+
+// 64bit 整数を Unicode 文字列に変換する
+void UniToStr64(wchar_t *str, UINT64 value)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	ToStr64(tmp, value);
+
+	StrToUni(str, 0, tmp);
+}
+
+// ANSI を UTF に変換する
+UINT StrToUtf(char *utfstr, UINT size, char *str)
+{
+	char *tmp;
+	// 引数チェック
+	if (utfstr == NULL || str == NULL)
+	{
+		StrCpy(utfstr, size, "");
+		return 0;
+	}
+
+	tmp = CopyStrToUtf(str);
+
+	StrCpy(utfstr, size, tmp);
+
+	Free(tmp);
+
+	return StrLen(utfstr);
+}
+
+// UTF を ANSI に変換する
+UINT UtfToStr(char *str, UINT size, char *utfstr)
+{
+	char *tmp;
+	// 引数チェック
+	if (str == NULL || utfstr == NULL)
+	{
+		StrCpy(str, size, "");
+		return 0;
+	}
+
+	tmp = CopyUtfToStr(utfstr);
+
+	StrCpy(str, size, tmp);
+
+	Free(tmp);
+
+	return StrLen(str);
+}
+
+// Unicode を UTF に変換する
+UINT UniToUtf(char *utfstr, UINT size, wchar_t *unistr)
+{
+	char *tmp;
+	// 引数チェック
+	if (utfstr == NULL || unistr == NULL)
+	{
+		StrCpy(utfstr, size, "");
+		return 0;
+	}
+
+	tmp = CopyUniToStr(unistr);
+
+	StrCpy(utfstr, size, tmp);
+
+	Free(tmp);
+
+	return StrLen(utfstr);
+}
+
+// UTF を Unicode に変換する
+UINT UtfToUni(wchar_t *unistr, UINT size, char *utfstr)
+{
+	wchar_t *tmp;
+	// 引数チェック
+	if (unistr == NULL || utfstr == NULL)
+	{
+		UniStrCpy(unistr, size, L"");
+		return 0;
+	}
+
+	tmp = CopyUtfToUni(utfstr);
+
+	UniStrCpy(unistr, size, tmp);
+
+	Free(tmp);
+
+	return UniStrLen(unistr);
+}
+
+// UTF8 文字列を Unicode 文字列にコピーする
+wchar_t *CopyUtfToUni(char *utfstr)
+{
+	UINT size;
+	wchar_t *ret;
+	UINT utfstr_len;
+	// 引数チェック
+	if (utfstr == NULL)
+	{
+		return NULL;
+	}
+
+	utfstr_len = StrLen(utfstr);
+
+	size = CalcUtf8ToUni((BYTE *)utfstr, utfstr_len);
+	ret = ZeroMalloc(size + sizeof(wchar_t));
+	Utf8ToUni(ret, size, (BYTE *)utfstr, utfstr_len);
+
+	return ret;
+}
+
+// UTF8 文字列を ANSI 文字列にコピーする
+char *CopyUtfToStr(char *utfstr)
+{
+	wchar_t *uni;
+	char *ret;
+	// 引数チェック
+	if (utfstr == NULL)
+	{
+		return NULL;
+	}
+
+	uni = CopyUtfToUni(utfstr);
+	if (uni == NULL)
+	{
+		return CopyStr("");
+	}
+
+	ret = CopyUniToStr(uni);
+
+	Free(uni);
+
+	return ret;
+}
+
+// Unicode 文字列を ANSI 文字列にコピーする
+char *CopyUniToStr(wchar_t *unistr)
+{
+	char *str;
+	UINT str_size;
+	// 引数チェック
+	if (unistr == NULL)
+	{
+		return NULL;
+	}
+
+	str_size = CalcUniToStr(unistr);
+	if (str_size == 0)
+	{
+		return CopyStr("");
+	}
+	str = Malloc(str_size);
+	UniToStr(str, str_size, unistr);
+
+	return str;
+}
+
+// ANSI 文字列を Unicode 文字列にコピーする
+wchar_t *CopyStrToUni(char *str)
+{
+	wchar_t *uni;
+	UINT uni_size;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	uni_size = CalcStrToUni(str);
+	if (uni_size == 0)
+	{
+		return CopyUniStr(L"");
+	}
+	uni = Malloc(uni_size);
+	StrToUni(uni, uni_size, str);
+
+	return uni;
+}
+
+// Unicode 文字列を UTF8 文字列にコピーする
+char *CopyUniToUtf(wchar_t *unistr)
+{
+	UINT size;
+	char *ret;
+	// 引数チェック
+	if (unistr == NULL)
+	{
+		return NULL;
+	}
+
+	size = CalcUniToUtf8(unistr);
+	ret = ZeroMalloc(size + sizeof(char));
+
+	UniToUtf8((char *)ret, size, unistr);
+
+	return ret;
+}
+
+// ANSI 文字列を UTF8 文字列にコピーする
+char *CopyStrToUtf(char *str)
+{
+	wchar_t *unistr;
+	char *ret;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	unistr = CopyStrToUni(str);
+	if (unistr == NULL)
+	{
+		return CopyStr("");
+	}
+
+	ret = CopyUniToUtf(unistr);
+
+	Free(unistr);
+
+	return ret;
+}
+
+// Unicode 文字列をコピーする
+wchar_t *CopyUniStr(wchar_t *str)
+{
+	UINT len;
+	wchar_t *dst;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	len = UniStrLen(str);
+	dst = Malloc((len + 1) * sizeof(wchar_t));
+	UniStrCpy(dst, 0, str);
+
+	return dst;
+}
+
+// 安全な文字列かどうかチェック
+bool IsSafeUniStr(wchar_t *str)
+{
+	UINT i, len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	len = UniStrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		if (IsSafeUniChar(str[i]) == false)
+		{
+			return false;
+		}
+	}
+	if (str[0] == L' ')
+	{
+		return false;
+	}
+	if (len != 0)
+	{
+		if (str[len - 1] == L' ')
+		{
+			return false;
+		}
+	}
+	return true;
+}
+
+// 安全な文字かどうかチェック
+bool IsSafeUniChar(wchar_t c)
+{
+	UINT i, len;
+	wchar_t *check_str =
+		L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+		L"abcdefghijklmnopqrstuvwxyz"
+		L"0123456789"
+		L" ()-_#%&.";
+
+	len = UniStrLen(check_str);
+	for (i = 0;i < len;i++)
+	{
+		if (c == check_str[i])
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
+// UTF-8 文字列を ANSI 文字列に変換する
+UINT Utf8ToStr(char *str, UINT str_size, BYTE *u, UINT size)
+{
+	UINT ret, uni_size;
+	wchar_t *tmp;
+	// 引数チェック
+	if (u == NULL || str == NULL)
+	{
+		return 0;
+	}
+
+	// Unicode に変換する
+	uni_size = CalcUtf8ToUni(u, size);
+	if (uni_size == 0)
+	{
+		if (str_size >= 1)
+		{
+			StrCpy(str, 0, "");
+			return 0;
+		}
+	}
+	tmp = Malloc(uni_size);
+	Utf8ToUni(tmp, uni_size, u, size);
+
+	// ANSI に変換する
+	ret = UniToStr(str, str_size, tmp);
+	Free(tmp);
+
+	return ret;
+}
+
+// UTF-8 文字列を ANSI 文字列に変換した場合に必要なサイズを取得する
+UINT CalcUtf8ToStr(BYTE *u, UINT size)
+{
+	UINT ret, uni_size;
+	wchar_t *tmp;
+	// 引数チェック
+	if (u == NULL)
+	{
+		return 0;
+	}
+
+	// Unicode に変換する
+	uni_size = CalcUtf8ToUni(u, size);
+	if (uni_size == 0)
+	{
+		return 0;
+	}
+	tmp = Malloc(uni_size);
+	Utf8ToUni(tmp, uni_size, u, size);
+
+	// ANSI に変換する
+	ret = CalcUniToStr(tmp);
+	Free(tmp);
+
+	return ret;
+}
+
+// ANSI 文字列を UTF-8 文字列に変換する
+UINT StrToUtf8(BYTE *u, UINT size, char *str)
+{
+	UINT ret, uni_size;
+	wchar_t *tmp;
+	// 引数チェック
+	if (u == NULL || str == NULL)
+	{
+		return 0;
+	}
+
+	// Unicode に変換する
+	uni_size = CalcStrToUni(str);
+	if (uni_size == 0)
+	{
+		return 0;
+	}
+	tmp = Malloc(uni_size);
+	StrToUni(tmp, uni_size, str);
+
+	// UTF-8 に変換する
+	ret = UniToUtf8(u, size, tmp);
+
+	Free(tmp);
+
+	return ret;
+}
+
+// ANSI 文字列を UTF-8 文字列に変換するために必要なサイズを取得する
+UINT CalcStrToUtf8(char *str)
+{
+	UINT ret;
+	UINT uni_size;
+	wchar_t *tmp;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	// Unicode に変換する
+	uni_size = CalcStrToUni(str);
+	if (uni_size == 0)
+	{
+		return 0;
+	}
+	tmp = Malloc(uni_size);
+	StrToUni(tmp, uni_size, str);
+
+	// UTF-8 に変換した場合のサイズを取得する
+	ret = CalcUniToUtf8(tmp);
+	Free(tmp);
+
+	return ret;
+}
+
+// Unicode 文字列を ANSI 文字列に変換する
+UINT UniToStr(char *str, UINT size, wchar_t *s)
+{
+#ifdef	OS_WIN32
+	UINT ret;
+	char *tmp;
+	UINT new_size;
+	// 引数チェック
+	if (s == NULL || str == NULL)
+	{
+		return 0;
+	}
+
+	new_size = CalcUniToStr(s);
+	if (new_size == 0)
+	{
+		if (size >= 1)
+		{
+			StrCpy(str, 0, "");
+		}
+		return 0;
+	}
+	tmp = Malloc(new_size);
+	tmp[0] = 0;
+	wcstombs(tmp, s, new_size);
+	tmp[new_size - 1] = 0;
+	ret = StrCpy(str, size, tmp);
+	Free(tmp);
+
+	return ret;
+#else	// OS_WIN32
+	return UnixUniToStr(str, size, s);
+#endif	// OS_WIN32
+}
+
+// Unicode 文字列を ANSI 文字列に変換するための必要なバイト数を取得する
+UINT CalcUniToStr(wchar_t *s)
+{
+#ifdef	OS_WIN32
+	UINT ret;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return 0;
+	}
+
+	ret = (UINT)wcstombs(NULL, s, UniStrLen(s));
+	if (ret == (UINT)-1)
+	{
+		return 0;
+	}
+
+	return ret + 1;
+#else	// OS_WIN32
+	return UnixCalcUniToStr(s);
+#endif	// OS_WIN32
+}
+
+// ANSI 文字列を Unicode 文字列に変換する
+UINT StrToUni(wchar_t *s, UINT size, char *str)
+{
+#ifdef	OS_WIN32
+	UINT ret;
+	wchar_t *tmp;
+	UINT new_size;
+	// 引数チェック
+	if (s == NULL || str == NULL)
+	{
+		return 0;
+	}
+
+	new_size = CalcStrToUni(str);
+	if (new_size == 0)
+	{
+		if (size >= 2)
+		{
+			UniStrCpy(s, 0, L"");
+		}
+		return 0;
+	}
+	tmp = Malloc(new_size);
+	tmp[0] = 0;
+	mbstowcs(tmp, str, StrLen(str));
+	tmp[(new_size - 1) / sizeof(wchar_t)] = 0;
+	ret = UniStrCpy(s, size, tmp);
+	Free(tmp);
+
+	return ret;
+#else	// OS_WIN32
+	return UnixStrToUni(s, size, str);
+#endif	// OS_WIN32
+}
+
+// ANSI 文字列を Unicode 文字列に変換するための必要なバイト数を取得する
+UINT CalcStrToUni(char *str)
+{
+#ifdef	OS_WIN32
+	UINT ret;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	ret = (UINT)mbstowcs(NULL, str, StrLen(str));
+	if (ret == (UINT)-1)
+	{
+		return 0;
+	}
+
+	return (ret + 1) * sizeof(wchar_t);
+#else	// OS_WIN32
+	return UnixCalcStrToUni(str);
+#endif	// OS_WIN32
+}
+
+// UTF-8 文字列を Unicode 文字列に変換する
+UINT Utf8ToUni(wchar_t *s, UINT size, BYTE *u, UINT u_size)
+{
+	UINT i, wp, num;
+	// 引数チェック
+	if (s == NULL || u == NULL)
+	{
+		return 0;
+	}
+	if (size == 0)
+	{
+		size = 0x3fffffff;
+	}
+	if (u_size == 0)
+	{
+		u_size = StrLen((char *)u);
+	}
+
+	i = 0;
+	wp = 0;
+	num = 0;
+	while (true)
+	{
+		UINT type;
+		wchar_t c;
+		BYTE c1, c2;
+
+		type = GetUtf8Type(u, u_size, i);
+		if (type == 0)
+		{
+			break;
+		}
+		switch (type)
+		{
+		case 1:
+			c1 = 0;
+			c2 = u[i];
+			break;
+		case 2:
+			c1 = (((u[i] & 0x1c) >> 2) & 0x07);
+			c2 = (((u[i] & 0x03) << 6) & 0xc0) | (u[i + 1] & 0x3f);
+			break;
+		case 3:
+			c1 = ((((u[i] & 0x0f) << 4) & 0xf0)) | (((u[i + 1] & 0x3c) >> 2) & 0x0f);
+			c2 = (((u[i + 1] & 0x03) << 6) & 0xc0) | (u[i + 2] & 0x3f);
+			break;
+		}
+		i += type;
+
+		c = 0;
+
+		if (IsBigEndian())
+		{
+			if (sizeof(wchar_t) == 2)
+			{
+				((BYTE *)&c)[0] = c1;
+				((BYTE *)&c)[1] = c2;
+			}
+			else
+			{
+				((BYTE *)&c)[2] = c1;
+				((BYTE *)&c)[3] = c2;
+			}
+		}
+		else
+		{
+			((BYTE *)&c)[0] = c2;
+			((BYTE *)&c)[1] = c1;
+		}
+
+		if (wp < ((size / sizeof(wchar_t)) - 1))
+		{
+			s[wp++] = c;
+			num++;
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	if (wp < (size / sizeof(wchar_t)))
+	{
+		s[wp++] = 0;
+	}
+
+	return num;
+}
+
+// UTF-8 を Unicode に変換した場合のバッファサイズを取得する
+UINT CalcUtf8ToUni(BYTE *u, UINT u_size)
+{
+	// 引数チェック
+	if (u == NULL)
+	{
+		return 0;
+	}
+	if (u_size == 0)
+	{
+		u_size = StrLen((char *)u);
+	}
+
+	return (Utf8Len(u, u_size) + 1) * sizeof(wchar_t);
+}
+
+// UTF-8 文字列の文字数を取得する
+UINT Utf8Len(BYTE *u, UINT size)
+{
+	UINT i, num;
+	// 引数チェック
+	if (u == NULL)
+	{
+		return 0;
+	}
+	if (size == 0)
+	{
+		size = StrLen((char *)u);
+	}
+
+	i = num = 0;
+	while (true)
+	{
+		UINT type;
+
+		type = GetUtf8Type(u, size, i);
+		if (type == 0)
+		{
+			break;
+		}
+		i += type;
+		num++;
+	}
+
+	return num;
+}
+
+// Unicode 文字列を UTF-8 文字列に変換する
+UINT UniToUtf8(BYTE *u, UINT size, wchar_t *s)
+{
+	UINT i, len, type, wp;
+	// 引数チェック
+	if (u == NULL || s == NULL)
+	{
+		return 0;
+	}
+	if (size == 0)
+	{
+		size = 0x3fffffff;
+	}
+
+	len = UniStrLen(s);
+	wp = 0;
+	for (i = 0;i < len;i++)
+	{
+		BYTE c1, c2;
+		wchar_t c = s[i];
+
+		if (IsBigEndian())
+		{
+			if (sizeof(wchar_t) == 2)
+			{
+				c1 = ((BYTE *)&c)[0];
+				c2 = ((BYTE *)&c)[1];
+			}
+			else
+			{
+				c1 = ((BYTE *)&c)[2];
+				c2 = ((BYTE *)&c)[3];
+			}
+		}
+		else
+		{
+			c1 = ((BYTE *)&c)[1];
+			c2 = ((BYTE *)&c)[0];
+		}
+
+		type = GetUniType(s[i]);
+		switch (type)
+		{
+		case 1:
+			if (wp < size)
+			{
+				u[wp++] = c2;
+			}
+			break;
+		case 2:
+			if (wp < size)
+			{
+				u[wp++] = 0xc0 | (((((c1 & 0x07) << 2) & 0x1c)) | (((c2 & 0xc0) >> 6) & 0x03));
+			}
+			if (wp < size)
+			{
+				u[wp++] = 0x80 | (c2 & 0x3f);
+			}
+			break;
+		case 3:
+			if (wp < size)
+			{
+				u[wp++] = 0xe0 | (((c1 & 0xf0) >> 4) & 0x0f);
+			}
+			if (wp < size)
+			{
+				u[wp++] = 0x80 | (((c1 & 0x0f) << 2) & 0x3c) | (((c2 & 0xc0) >> 6) & 0x03);
+			}
+			if (wp < size)
+			{
+				u[wp++] = 0x80 | (c2 & 0x3f);
+			}
+			break;
+		}
+	}
+	if (wp < size)
+	{
+		u[wp] = 0;
+	}
+	return wp;
+}
+
+// Unicode 文字列を UTF-8 文字列に変換した場合の文字列長を計算する
+UINT CalcUniToUtf8(wchar_t *s)
+{
+	UINT i, len, size;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return 0;
+	}
+
+	size = 0;
+	len = UniStrLen(s);
+	for (i = 0;i < len;i++)
+	{
+		size += GetUniType(s[i]);
+	}
+
+	return size;
+}
+
+// s で始まる UTF-8 文字列の offset 番地の最初の 1 文字が何バイトで構成されているかを取得
+UINT GetUtf8Type(BYTE *s, UINT size, UINT offset)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return 0;
+	}
+	if ((offset + 1) > size)
+	{
+		return 0;
+	}
+	if ((s[offset] & 0x80) == 0)
+	{
+		// 1 バイト
+		return 1;
+	}
+	if ((s[offset] & 0x20) == 0)
+	{
+		// 2 バイト
+		if ((offset + 2) > size)
+		{
+			return 0;
+		}
+		return 2;
+	}
+	// 3 バイト
+	if ((offset + 3) > size)
+	{
+		return 0;
+	}
+	return 3;
+}
+
+// 文字 c を UTF-8 に変換した場合の種類 (バイト数)
+UINT GetUniType(wchar_t c)
+{
+	BYTE c1, c2;
+
+	if (IsBigEndian())
+	{
+		if (sizeof(wchar_t) == 2)
+		{
+			c1 = ((BYTE *)&c)[0];
+			c2 = ((BYTE *)&c)[1];
+		}
+		else
+		{
+			c1 = ((BYTE *)&c)[2];
+			c2 = ((BYTE *)&c)[3];
+		}
+	}
+	else
+	{
+		c1 = ((BYTE *)&c)[1];
+		c2 = ((BYTE *)&c)[0];
+	}
+
+	if (c1 == 0)
+	{
+		if (c2 <= 0x7f)
+		{
+			// 1 バイト
+			return 1;
+		}
+		else
+		{
+			// 2 バイト
+			return 2;
+		}
+	}
+	if ((c1 & 0xf8) == 0)
+	{
+		// 2 バイト
+		return 2;
+	}
+	// 3 バイト
+	return 3;
+}
+
+// 文字列の置換 (大文字小文字を区別しない)
+UINT UniReplaceStri(wchar_t *dst, UINT size, wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword)
+{
+	return UniReplaceStrEx(dst, size, string, old_keyword, new_keyword, false);
+}
+
+// 文字列の置換 (大文字小文字を区別する)
+UINT UniReplaceStr(wchar_t *dst, UINT size, wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword)
+{
+	return UniReplaceStrEx(dst, size, string, old_keyword, new_keyword, true);
+}
+
+// 文字列の置換
+UINT UniReplaceStrEx(wchar_t *dst, UINT size, wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword, bool case_sensitive)
+{
+	UINT i, j, num, len_string, len_old, len_new, len_ret, wp;
+	wchar_t *ret;
+	// 引数チェック
+	if (string == NULL || old_keyword == NULL || new_keyword == NULL)
+	{
+		return 0;
+	}
+
+	// 文字列長の取得
+	len_string = UniStrLen(string);
+	len_old = UniStrLen(old_keyword);
+	len_new = UniStrLen(new_keyword);
+
+	// 最終文字列長の取得
+	len_ret = UniCalcReplaceStrEx(string, old_keyword, new_keyword, case_sensitive);
+	// メモリ確保
+	ret = Malloc((len_ret + 1) * sizeof(wchar_t));
+	ret[len_ret] = 0;
+
+	// 検索と置換
+	i = j = num = wp = 0;
+	while (true)
+	{
+		i = UniSearchStrEx(string, old_keyword, i, case_sensitive);
+		if (i == INFINITE)
+		{
+			Copy(&ret[wp], &string[j], (len_string - j) * sizeof(wchar_t));
+			wp += len_string - j;
+			break;
+		}
+		num++;
+		Copy(&ret[wp], &string[j], (i - j) * sizeof(wchar_t));
+		wp += i - j;
+		Copy(&ret[wp], new_keyword, len_new * sizeof(wchar_t));
+		wp += len_new;
+		i += len_old;
+		j = i;
+	}
+
+	// 検索結果のコピー
+	UniStrCpy(dst, size, ret);
+
+	// メモリ解放
+	Free(ret);
+
+	return num;
+}
+
+// 文字列の置換後の文字列長を計算する
+UINT UniCalcReplaceStrEx(wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword, bool case_sensitive)
+{
+	UINT i, num;
+	UINT len_string, len_old, len_new;
+	// 引数チェック
+	if (string == NULL || old_keyword == NULL || new_keyword == NULL)
+	{
+		return 0;
+	}
+
+	// 文字列長の取得
+	len_string = UniStrLen(string);
+	len_old = UniStrLen(old_keyword);
+	len_new = UniStrLen(new_keyword);
+
+	if (len_old == len_new)
+	{
+		return len_string;
+	}
+
+	// 検索処理
+	num = 0;
+	i = 0;
+	while (true)
+	{
+		i = UniSearchStrEx(string, old_keyword, i, case_sensitive);
+		if (i == INFINITE)
+		{
+			break;
+		}
+		i += len_old;
+		num++;
+	}
+
+	// 計算
+	return len_string + len_new * num - len_old * num;
+}
+
+// 文字列の検索 (大文字 / 小文字を区別する)
+UINT UniSearchStr(wchar_t *string, wchar_t *keyword, UINT start)
+{
+	return UniSearchStrEx(string, keyword, start, true);
+}
+
+// 文字列の検索 (大文字 / 小文字を区別しない)
+UINT UniSearchStri(wchar_t *string, wchar_t *keyword, UINT start)
+{
+	return UniSearchStrEx(string, keyword, start, false);
+}
+
+// 文字列 string から文字列 keyword を検索して最初に見つかった文字の場所を返す
+// (1文字目に見つかったら 0, 見つからなかったら INFINITE)
+UINT UniSearchStrEx(wchar_t *string, wchar_t *keyword, UINT start, bool case_sensitive)
+{
+	UINT len_string, len_keyword;
+	UINT i;
+	wchar_t *cmp_string, *cmp_keyword;
+	bool found;
+	// 引数チェック
+	if (string == NULL || keyword == NULL)
+	{
+		return INFINITE;
+	}
+
+	// string の長さを取得
+	len_string = UniStrLen(string);
+	if (len_string <= start)
+	{
+		// start の値が不正
+		return INFINITE;
+	}
+
+	// keyword の長さを取得
+	len_keyword = UniStrLen(keyword);
+	if (len_keyword == 0)
+	{
+		// キーワードが無い
+		return INFINITE;
+	}
+
+	if (len_string < len_keyword)
+	{
+		return INFINITE;
+	}
+
+	if (len_string == len_keyword)
+	{
+		if (case_sensitive)
+		{
+			if (UniStrCmp(string, keyword) == 0)
+			{
+				return 0;
+			}
+			else
+			{
+				return INFINITE;
+			}
+		}
+		else
+		{
+			if (UniStrCmpi(string, keyword) == 0)
+			{
+				return 0;
+			}
+			else
+			{
+				return INFINITE;
+			}
+		}
+	}
+
+	if (case_sensitive)
+	{
+		cmp_string = string;
+		cmp_keyword = keyword;
+	}
+	else
+	{
+		cmp_string = Malloc((len_string + 1) * sizeof(wchar_t));
+		UniStrCpy(cmp_string, (len_string + 1) * sizeof(wchar_t), string);
+		cmp_keyword = Malloc((len_keyword + 1) * sizeof(wchar_t));
+		UniStrCpy(cmp_keyword, (len_keyword + 1) * sizeof(wchar_t), keyword);
+		UniStrUpper(cmp_string);
+		UniStrUpper(cmp_keyword);
+	}
+
+	// 検索
+	found = false;
+	for (i = start;i < (len_string - len_keyword + 1);i++)
+	{
+		// 比較する
+		if (!wcsncmp(&cmp_string[i], cmp_keyword, len_keyword))
+		{
+			// 発見した
+			found = true;
+			break;
+		}
+	}
+
+	if (case_sensitive == false)
+	{
+		// メモリ解放
+		Free(cmp_keyword);
+		Free(cmp_string);
+	}
+
+	if (found == false)
+	{
+		return INFINITE;
+	}
+	return i;
+}
+
+// トークンリストの解放
+void UniFreeToken(UNI_TOKEN_LIST *tokens)
+{
+	UINT i;
+	if (tokens == NULL)
+	{
+		return;
+	}
+	for (i = 0;i < tokens->NumTokens;i++)
+	{
+		Free(tokens->Token[i]);
+	}
+	Free(tokens->Token);
+	Free(tokens);
+}
+
+// UNIX 版トークンのパース
+UNI_TOKEN_LIST *UnixUniParseToken(wchar_t *src, wchar_t *separator)
+{
+	UNI_TOKEN_LIST *ret;
+	TOKEN_LIST *t;
+	char *src_s;
+	char *sep_s;
+
+	// 引数チェック
+	if (src == NULL || separator == NULL)
+	{
+		ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
+		ret->Token = ZeroMalloc(0);
+		return ret;
+	}
+
+	src_s = CopyUniToStr(src);
+	sep_s = CopyUniToStr(separator);
+
+	t = ParseToken(src_s, sep_s);
+
+	ret = TokenListToUniTokenList(t);
+	FreeToken(t);
+
+	Free(src_s);
+	Free(sep_s);
+
+	return ret;
+}
+
+// トークンのパース
+UNI_TOKEN_LIST *UniParseToken(wchar_t *src, wchar_t *separator)
+{
+#ifdef	OS_WIN32
+	UNI_TOKEN_LIST *ret;
+	wchar_t *tmp;
+	wchar_t *str1, *str2;
+	UINT len, num;
+
+#ifdef	OS_UNIX
+	wchar_t *state = NULL;
+#endif	// OS_UNIX
+
+	// 引数チェック
+	if (src == NULL)
+	{
+		ret = ZeroMalloc(sizeof(UNI_TOKEN_LIST));
+		ret->Token = ZeroMalloc(0);
+		return ret;
+	}
+	if (separator == NULL)
+	{
+		separator = L" .\t\r\n";
+	}
+	len = UniStrLen(src);
+	str1 = Malloc((len + 1) * sizeof(wchar_t));
+	str2 = Malloc((len + 1) * sizeof(wchar_t));
+	UniStrCpy(str1, 0, src);
+	UniStrCpy(str2, 0, src);
+
+	Lock(token_lock);
+	{
+		tmp = wcstok(str1, separator
+#ifdef	OS_UNIX
+			, &state
+#endif	// OS_UNIX
+			);
+		num = 0;
+		while (tmp != NULL)
+		{
+			num++;
+			tmp = wcstok(NULL, separator
+#ifdef	OS_UNIX
+				, &state
+#endif	// OS_UNIX
+				);
+		}
+		ret = Malloc(sizeof(UNI_TOKEN_LIST));
+		ret->NumTokens = num;
+		ret->Token = (wchar_t **)Malloc(sizeof(wchar_t *) * num);
+		num = 0;
+		tmp = wcstok(str2, separator
+#ifdef	OS_UNIX
+			, &state
+#endif	// OS_UNIX
+			);
+		while (tmp != NULL)
+		{
+			ret->Token[num] = (wchar_t *)Malloc((UniStrLen(tmp) + 1) * sizeof(wchar_t));
+			UniStrCpy(ret->Token[num], 0, tmp);
+			num++;
+			tmp = wcstok(NULL, separator
+#ifdef	OS_UNIX
+				, &state
+#endif	// OS_UNIX
+				);
+		}
+	}
+	Unlock(token_lock);
+
+	Free(str1);
+	Free(str2);
+	return ret;
+#else	// OS_WIN32
+	return UnixUniParseToken(src, separator);
+#endif	// OS_WIN32
+}
+
+// 1 行を標準入力から取得
+bool UniGetLine(wchar_t *str, UINT size)
+{
+#ifdef	OS_WIN32
+	return UniGetLineWin32(str, size);
+#else	// OS_WIN32
+	return UniGetLineUnix(str, size);
+#endif	// OS_WIN32
+}
+void AnsiGetLineUnix(char *str, UINT size)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		char tmp[MAX_SIZE];
+		fgets(tmp, sizeof(tmp) - 1, stdin);
+		return;
+	}
+	if (size <= 1)
+	{
+		return;
+	}
+
+	// 標準入力からデータを読み込み
+	fgets(str, (int)(size - 1), stdin);
+
+	TrimCrlf(str);
+}
+bool UniGetLineUnix(wchar_t *str, UINT size)
+{
+	char *str_a;
+	UINT str_a_size = size;
+	if (str == NULL || size < sizeof(wchar_t))
+	{
+		return false;
+	}
+	if (str_a_size >= 0x7fffffff)
+	{
+		str_a_size = MAX_SIZE;
+	}
+	str_a_size *= 2;
+
+	str_a = ZeroMalloc(str_a_size);
+
+	AnsiGetLineUnix(str_a, str_a_size);
+
+	StrToUni(str, size, str_a);
+
+	Free(str_a);
+
+	return true;
+}
+bool UniGetLineWin32(wchar_t *str, UINT size)
+{
+	bool ret = false;
+
+#ifdef	OS_WIN32
+	ret = Win32InputW(str, size);
+#endif	// OS_WIN32
+
+	return ret;
+}
+
+// 末尾の \r \n を削除
+void UniTrimCrlf(wchar_t *str)
+{
+	UINT len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+	len = UniStrLen(str);
+	if (len == 0)
+	{
+		return;
+	}
+
+	if (str[len - 1] == L'\n')
+	{
+		if (len >= 2 && str[len - 2] == L'\r')
+		{
+			str[len - 2] = 0;
+		}
+		str[len - 1] = 0;
+	}
+	else if(str[len - 1] == L'\r')
+	{
+		str[len - 1] = 0;
+	}
+}
+
+// 文字列の左右の空白を削除
+void UniTrim(wchar_t *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	UniTrimLeft(str);
+	UniTrimRight(str);
+}
+
+// 文字列の右側の空白を削除
+void UniTrimRight(wchar_t *str)
+{
+	wchar_t *buf, *tmp;
+	UINT len, i, wp, wp2;
+	bool flag;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+	len = UniStrLen(str);
+	if (len == 0)
+	{
+		return;
+	}
+	if (str[len - 1] != L' ' && str[len - 1] != L'\t')
+	{
+		return;
+	}
+
+	buf = Malloc((len + 1) * sizeof(wchar_t));
+	tmp = Malloc((len + 1) * sizeof(wchar_t));
+	flag = false;
+	wp = wp2 = 0;
+	for (i = 0;i < len;i++)
+	{
+		if (str[i] != L' ' && str[i] != L'\t')
+		{
+			Copy(&buf[wp], tmp, wp2 * sizeof(wchar_t));
+			wp += wp2;
+			wp2 = 0;
+			buf[wp++] = str[i];
+		}
+		else
+		{
+			tmp[wp2++] = str[i];
+		}
+	}
+	buf[wp] = 0;
+	UniStrCpy(str, 0, buf);
+	Free(buf);
+	Free(tmp);
+}
+
+// 文字列の左側の空白を削除
+void UniTrimLeft(wchar_t *str)
+{
+	wchar_t *buf;
+	UINT len, i, wp;
+	bool flag;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+	len = UniStrLen(str);
+	if (len == 0)
+	{
+		return;
+	}
+	if (str[0] != L' ' && str[0] != L'\t')
+	{
+		return;
+	}
+
+	buf = Malloc((len + 1) * sizeof(wchar_t));
+	flag = false;
+	wp = 0;
+	for (i = 0;i < len;i++)
+	{
+		if (str[i] != L' ' && str[i] != L'\t')
+		{
+			flag = true;
+		}
+		if (flag)
+		{
+			buf[wp++] = str[i];
+		}
+	}
+	buf[wp] = 0;
+	UniStrCpy(str, 0, buf);
+	Free(buf);
+}
+
+// 整数を 16 進文字列に変換 (8桁固定)
+void UniToStrx8(wchar_t *str, UINT i)
+{
+	UniFormat(str, 0, L"0x%08x", i);
+}
+
+// 整数を 16 進文字列に変換
+void UniToStrx(wchar_t *str, UINT i)
+{
+	UniFormat(str, 0, L"0x%02x", i);
+}
+
+// 符号付整数を文字列に変換
+void UniToStri(wchar_t *str, int i)
+{
+	UniFormat(str, 0, L"%i", i);
+}
+
+// 整数を文字列に変換
+void UniToStru(wchar_t *str, UINT i)
+{
+	UniFormat(str, 0, L"%u", i);
+}
+
+// 文字列を符号付整数に変換
+int UniToInti(wchar_t *str)
+{
+	char tmp[128];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	UniToStr(tmp, sizeof(tmp), str);
+
+	return ToInt(tmp);
+}
+
+// 文字列を整数に変換
+UINT UniToInt(wchar_t *str)
+{
+	char tmp[128];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	UniToStr(tmp, sizeof(tmp), str);
+
+	return ToInti(tmp);
+}
+
+// 64bit 用フォーマット文字列置換
+wchar_t *UniReplaceFormatStringFor64(wchar_t *fmt)
+{
+	wchar_t *tmp;
+	wchar_t *ret;
+	UINT tmp_size;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return NULL;
+	}
+
+	tmp_size = UniStrSize(fmt) * 2;
+	tmp = ZeroMalloc(tmp_size);
+
+#ifdef	OS_WIN32
+	UniReplaceStrEx(tmp, tmp_size, fmt, L"%ll", L"%I64", false);
+#else	// OS_WIN32
+	UniReplaceStrEx(tmp, tmp_size, fmt, L"%I64", L"%ll", false);
+
+	if (1)
+	{
+		UINT i, len;
+		bool f = false;
+		len = UniStrLen(tmp);
+		for (i = 0;i < len;i++)
+		{
+			if (tmp[i] == L'%')
+			{
+				f = true;
+			}
+
+			if (f)
+			{
+				switch (tmp[i])
+				{
+				case L'c':
+				case L'C':
+				case L'd':
+				case L'i':
+				case L'o':
+				case L'u':
+				case L'x':
+				case L'X':
+				case L'e':
+				case L'E':
+				case L'f':
+				case L'g':
+				case L'G':
+				case L'n':
+				case L'p':
+				case L's':
+				case L'S':
+					if (tmp[i] == L's')
+					{
+						tmp[i] = L'S';
+					}
+					else if (tmp[i] == L'S')
+					{
+						tmp[i] = L's';
+					}
+					f = false;
+					break;
+				}
+			}
+		}
+	}
+
+#endif	// OS_WIN32
+
+	ret = CopyUniStr(tmp);
+	Free(tmp);
+
+	return ret;
+}
+
+// 文字列を画面に表示する
+void UniPrintStr(wchar_t *string)
+{
+	// 引数チェック
+	if (string == NULL)
+	{
+		return;
+	}
+
+#ifdef	OS_UNIX
+	if (true)
+	{
+		char *str = CopyUniToStr(string);
+
+		if (str != NULL)
+		{
+			fputs(str, stdout);
+		}
+		else
+		{
+			fputs("", stdout);
+		}
+
+		Free(str);
+	}
+#else	// OS_UNIX
+	Win32PrintW(string);
+#endif	// OS_UNIX
+}
+
+// 文字列を引数付きで表示する
+void UniPrintArgs(wchar_t *fmt, va_list args)
+{
+	wchar_t *str;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return;
+	}
+
+	str = InternalFormatArgs(fmt, args, false);
+
+	UniPrintStr(str);
+
+	Free(str);
+}
+
+// 文字列を表示する
+void UniPrint(wchar_t *fmt, ...)
+{
+	va_list args;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return;
+	}
+
+	va_start(args, fmt);
+	UniPrintArgs(fmt, args);
+	va_end(args);
+}
+
+// デバッグ文字列を引数付きで表示する
+void UniDebugArgs(wchar_t *fmt, va_list args)
+{
+	if (g_debug == false)
+	{
+		return;
+	}
+
+	UniPrintArgs(fmt, args);
+}
+
+// デバッグ文字列を表示する
+void UniDebug(wchar_t *fmt, ...)
+{
+	va_list args;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return;
+	}
+
+	va_start(args, fmt);
+	UniDebugArgs(fmt, args);
+	va_end(args);
+}
+
+// 文字列をフォーマットする (引数リスト)
+void UniFormatArgs(wchar_t *buf, UINT size, wchar_t *fmt, va_list args)
+{
+	wchar_t *ret;
+	// 引数チェック
+	if (buf == NULL || fmt == NULL)
+	{
+		return;
+	}
+	if (size == 1)
+	{
+		return;
+	}
+
+	// KS
+	KS_INC(KS_FORMAT_COUNT);
+
+	ret = InternalFormatArgs(fmt, args, false);
+
+	UniStrCpy(buf, size, ret);
+
+	Free(ret);
+}
+
+// 文字列をフォーマットして結果をコピーする
+wchar_t *CopyUniFormat(wchar_t *fmt, ...)
+{
+	wchar_t *ret, *str;
+	UINT size;
+	va_list args;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return NULL;
+	}
+
+	size = MAX(UniStrSize(fmt) * 10, MAX_SIZE * 10);
+	str = Malloc(size);
+
+	va_start(args, fmt);
+	UniFormatArgs(str, size, fmt, args);
+
+	ret = UniCopyStr(str);
+	Free(str);
+	va_end(args);
+
+	return ret;
+}
+
+// 文字列をフォーマットする
+void UniFormat(wchar_t *buf, UINT size, wchar_t *fmt, ...)
+{
+	va_list args;
+	// 引数チェック
+	if (buf == NULL || fmt == NULL)
+	{
+		return;
+	}
+
+	va_start(args, fmt);
+	UniFormatArgs(buf, size, fmt, args);
+	va_end(args);
+}
+
+// 柔軟な文字列比較
+int UniSoftStrCmp(wchar_t *str1, wchar_t *str2)
+{
+	UINT ret;
+	wchar_t *tmp1, *tmp2;
+	// 引数チェック
+	if (str1 == NULL && str2 == NULL)
+	{
+		return 0;
+	}
+	if (str1 == NULL)
+	{
+		return 1;
+	}
+	if (str2 == NULL)
+	{
+		return -1;
+	}
+
+	tmp1 = CopyUniStr(str1);
+	tmp2 = CopyUniStr(str2);
+
+	UniTrim(tmp1);
+	UniTrim(tmp2);
+
+	ret = UniStrCmpi(tmp1, tmp2);
+
+	Free(tmp1);
+	Free(tmp2);
+
+	return ret;
+}
+
+// 文字列を大文字・小文字を区別せずに比較する
+int UniStrCmpi(wchar_t *str1, wchar_t *str2)
+{
+	UINT i;
+	// 引数チェック
+	if (str1 == NULL && str2 == NULL)
+	{
+		return 0;
+	}
+	if (str1 == NULL)
+	{
+		return 1;
+	}
+	if (str2 == NULL)
+	{
+		return -1;
+	}
+
+	// 文字列比較
+	i = 0;
+	while (true)
+	{
+		wchar_t c1, c2;
+		c1 = UniToUpper(str1[i]);
+		c2 = UniToUpper(str2[i]);
+		if (c1 > c2)
+		{
+			return 1;
+		}
+		else if (c1 < c2)
+		{
+			return -1;
+		}
+		if (str1[i] == 0 || str2[i] == 0)
+		{
+			return 0;
+		}
+		i++;
+	}
+}
+
+// 文字列を比較する
+int UniStrCmp(wchar_t *str1, wchar_t *str2)
+{
+	// 引数チェック
+	if (str1 == NULL && str2 == NULL)
+	{
+		return 0;
+	}
+	if (str1 == NULL)
+	{
+		return 1;
+	}
+	if (str2 == NULL)
+	{
+		return -1;
+	}
+
+	return wcscmp(str1, str2);
+}
+
+// 文字列を小文字にする
+void UniStrLower(wchar_t *str)
+{
+	UINT i, len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	len = UniStrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		str[i] = UniToLower(str[i]);
+	}
+}
+
+// 文字列を大文字にする
+void UniStrUpper(wchar_t *str)
+{
+	UINT i, len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	len = UniStrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		str[i] = UniToUpper(str[i]);
+	}
+}
+
+// 文字を小文字にする
+wchar_t UniToLower(wchar_t c)
+{
+	if (c >= L'A' && c <= L'Z')
+	{
+		c += L'a' - L'A';
+	}
+
+	return c;
+}
+
+// 文字を大文字にする
+wchar_t UniToUpper(wchar_t c)
+{
+	if (c >= L'a' && c <= L'z')
+	{
+		c -= L'a' - L'A';
+	}
+
+	return c;
+}
+
+// 文字列結合
+UINT UniStrCat(wchar_t *dst, UINT size, wchar_t *src)
+{
+	UINT len1, len2, len_test;
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return 0;
+	}
+	if (size != 0 && size < sizeof(wchar_t))
+	{
+		return 0;
+	}
+	if (size == sizeof(wchar_t))
+	{
+		wcscpy(dst, L"");
+		return 0;
+	}
+	if (size == 0)
+	{
+		// 長さ無視
+		size = 0x3fffffff;
+	}
+
+	len1 = UniStrLen(dst);
+	len2 = UniStrLen(src);
+	len_test = len1 + len2 + 1;
+	if (len_test > (size / sizeof(wchar_t)))
+	{
+		if (len2 <= (len_test - (size / sizeof(wchar_t))))
+		{
+			return 0;
+		}
+		len2 -= len_test - (size / sizeof(wchar_t));
+	}
+	Copy(&dst[len1], src, len2 * sizeof(wchar_t));
+	dst[len1 + len2] = 0;
+
+	return len1 + len2;
+}
+UINT UniStrCatLeft(wchar_t *dst, UINT size, wchar_t *src)
+{
+	wchar_t *s;
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return 0;
+	}
+
+	s = UniCopyStr(dst);
+	UniStrCpy(dst, size, s);
+	UniStrCat(dst, size, src);
+	Free(s);
+
+	return UniStrLen(dst);
+}
+
+// 文字列コピー
+UINT UniStrCpy(wchar_t *dst, UINT size, wchar_t *src)
+{
+	UINT len;
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		if (src == NULL && dst != NULL)
+		{
+			if (size >= sizeof(wchar_t))
+			{
+				dst[0] = L'\0';
+			}
+		}
+		return 0;
+	}
+	if (dst == src)
+	{
+		return UniStrLen(src);
+	}
+	if (size != 0 && size < sizeof(wchar_t))
+	{
+		return 0;
+	}
+	if (size == sizeof(wchar_t))
+	{
+		wcscpy(dst, L"");
+		return 0;
+	}
+	if (size == 0)
+	{
+		// 長さ無視
+		size = 0x3fffffff;
+	}
+
+	// 長さをチェック
+	len = UniStrLen(src);
+	if (len <= (size / sizeof(wchar_t) - 1))
+	{
+		Copy(dst, src, (len + 1) * sizeof(wchar_t));
+	}
+	else
+	{
+		len = size / 2 - 1;
+		Copy(dst, src, len * sizeof(wchar_t));
+		dst[len] = 0;
+	}
+
+	return len;
+}
+
+// 文字が指定されたバッファサイズ以内かどうかチェック
+bool UniCheckStrSize(wchar_t *str, UINT size)
+{
+	// 引数チェック
+	if (str == NULL || size <= 1)
+	{
+		return false;
+	}
+
+	return UniCheckStrLen(str, size / sizeof(wchar_t) - 1);
+}
+
+// 文字数が指定された長さ以内かどうかチェック
+bool UniCheckStrLen(wchar_t *str, UINT len)
+{
+	UINT count = 0;
+	UINT i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;;i++)
+	{
+		if (str[i] == 0)
+		{
+			return true;
+		}
+		count++;
+		if (count > len)
+		{
+			return false;
+		}
+	}
+}
+
+// 文字列の格納に必要なバッファサイズの取得
+UINT UniStrSize(wchar_t *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	return (UniStrLen(str) + 1) * sizeof(wchar_t);
+}
+
+// 文字列の長さの取得
+UINT UniStrLen(wchar_t *str)
+{
+	UINT i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	i = 0;
+	while (true)
+	{
+		if (str[i] == 0)
+		{
+			break;
+		}
+		i++;
+	}
+
+	return i;
+}
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Internat.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Internat.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Internat.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,217 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Internat.h
+// Internat.c のヘッダ
+
+#ifndef	INTERNAT_H
+#define	INTERNAT_H
+
+// 文字列トークン
+struct UNI_TOKEN_LIST
+{
+	UINT NumTokens;
+	wchar_t **Token;
+};
+
+UINT UniStrLen(wchar_t *str);
+UINT UniStrSize(wchar_t *str);
+UINT UniStrCpy(wchar_t *dst, UINT size, wchar_t *src);
+bool UniCheckStrSize(wchar_t *str, UINT size);
+bool UniCheckStrLen(wchar_t *str, UINT len);
+UINT UniStrCat(wchar_t *dst, UINT size, wchar_t *src);
+UINT UniStrCatLeft(wchar_t *dst, UINT size, wchar_t *src);
+wchar_t UniToLower(wchar_t c);
+wchar_t UniToUpper(wchar_t c);
+void UniStrLower(wchar_t *str);
+void UniStrUpper(wchar_t *str);
+int UniStrCmp(wchar_t *str1, wchar_t *str2);
+int UniStrCmpi(wchar_t *str1, wchar_t *str2);
+int UniSoftStrCmp(wchar_t *str1, wchar_t *str2);
+void UniFormat(wchar_t *buf, UINT size, wchar_t *fmt, ...);
+wchar_t *CopyUniFormat(wchar_t *fmt, ...);
+void UniFormatArgs(wchar_t *buf, UINT size, wchar_t *fmt, va_list args);
+void UniDebugArgs(wchar_t *fmt, va_list args);
+void UniDebug(wchar_t *fmt, ...);
+void UniPrint(wchar_t *fmt, ...);
+void UniPrintArgs(wchar_t *fmt, va_list args);
+void UniPrintStr(wchar_t *string);
+void UniToStrx8(wchar_t *str, UINT i);
+void UniToStrx(wchar_t *str, UINT i);
+void UniToStri(wchar_t *str, int i);
+void UniToStru(wchar_t *str, UINT i);
+int UniToInti(wchar_t *str);
+UINT UniToInt(wchar_t *str);
+void UniTrim(wchar_t *str);
+void UniTrimLeft(wchar_t *str);
+void UniTrimRight(wchar_t *str);
+void UniTrimCrlf(wchar_t *str);
+bool UniGetLine(wchar_t *str, UINT size);
+bool UniGetLineWin32(wchar_t *str, UINT size);
+bool UniGetLineUnix(wchar_t *str, UINT size);
+void UniFreeToken(UNI_TOKEN_LIST *tokens);
+UNI_TOKEN_LIST *UniParseToken(wchar_t *src, wchar_t *separator);
+UINT UniSearchStrEx(wchar_t *string, wchar_t *keyword, UINT start, bool case_sensitive);
+UINT UniSearchStri(wchar_t *string, wchar_t *keyword, UINT start);
+UINT UniSearchStr(wchar_t *string, wchar_t *keyword, UINT start);
+UINT UniCalcReplaceStrEx(wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword, bool case_sensitive);
+UINT UniReplaceStrEx(wchar_t *dst, UINT size, wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword, bool case_sensitive);
+UINT UniReplaceStri(wchar_t *dst, UINT size, wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword);
+UINT UniReplaceStr(wchar_t *dst, UINT size, wchar_t *string, wchar_t *old_keyword, wchar_t *new_keyword);
+UINT GetUniType(wchar_t c);
+UINT GetUtf8Type(BYTE *s, UINT size, UINT offset);
+UINT CalcUniToUtf8(wchar_t *s);
+UINT UniToUtf8(BYTE *u, UINT size, wchar_t *s);
+UINT Utf8Len(BYTE *u, UINT size);
+UINT CalcUtf8ToUni(BYTE *u, UINT u_size);
+UINT Utf8ToUni(wchar_t *s, UINT size, BYTE *u, UINT u_size);
+UINT CalcStrToUni(char *str);
+UINT StrToUni(wchar_t *s, UINT size, char *str);
+UINT CalcUniToStr(wchar_t *s);
+UINT UniToStr(char *str, UINT size, wchar_t *s);
+UINT CalcStrToUtf8(char *str);
+UINT StrToUtf8(BYTE *u, UINT size, char *str);
+UINT CalcUtf8ToStr(BYTE *u, UINT size);
+UINT Utf8ToStr(char *str, UINT str_size, BYTE *u, UINT size);
+bool IsSafeUniStr(wchar_t *str);
+bool IsSafeUniChar(wchar_t c);
+wchar_t *CopyUniStr(wchar_t *str);
+wchar_t *CopyStrToUni(char *str);
+UINT StrToUtf(char *utfstr, UINT size, char *str);
+UINT UtfToStr(char *str, UINT size, char *utfstr);
+UINT UniToUtf(char *utfstr, UINT size, wchar_t *unistr);
+UINT UtfToUni(wchar_t *unistr, UINT size, char *utfstr);
+char *CopyUniToUtf(wchar_t *unistr);
+char *CopyStrToUtf(char *str);
+char *CopyUniToStr(wchar_t *unistr);
+wchar_t *CopyUtfToUni(char *utfstr);
+char *CopyUtfToStr(char *utfstr);
+wchar_t *UniReplaceFormatStringFor64(wchar_t *fmt);
+void UniToStr64(wchar_t *str, UINT64 value);
+UINT64 UniToInt64(wchar_t *str);
+UNI_TOKEN_LIST *UniParseCmdLine(wchar_t *str);
+UNI_TOKEN_LIST *UniCopyToken(UNI_TOKEN_LIST *src);
+wchar_t *UniCopyStr(wchar_t *str);
+TOKEN_LIST *UniTokenListToTokenList(UNI_TOKEN_LIST *src);
+UNI_TOKEN_LIST *TokenListToUniTokenList(TOKEN_LIST *src);
+UNI_TOKEN_LIST *UniNullToken();
+UNI_TOKEN_LIST *NullUniToken();
+bool UniIsNum(wchar_t *str);
+bool IsEmptyUniStr(wchar_t *str);
+bool UniIsEmptyStr(wchar_t *str);
+void InitInternational();
+void FreeInternational();
+USHORT *WideToUtf16(wchar_t *str);
+wchar_t *Utf16ToWide(USHORT *str);
+void DumpUniStr(wchar_t *str);
+void DumpStr(char *str);
+wchar_t *InternalFormatArgs(wchar_t *fmt, va_list args, bool ansi_mode);
+UINT UniStrWidth(wchar_t *str);
+UNI_TOKEN_LIST *UnixUniParseToken(wchar_t *src, wchar_t *separator);
+void UniToStr3(wchar_t *str, UINT size, UINT64 value);
+bool UniEndWith(wchar_t *str, wchar_t *key);
+bool UniStartWith(wchar_t *str, wchar_t *key);
+wchar_t *UniNormalizeCrlf(wchar_t *str);
+LIST *UniStrToStrList(wchar_t *str, UINT size);
+BUF *UniStrListToStr(LIST *o);
+void UniFreeStrList(LIST *o);
+UNI_TOKEN_LIST *UniListToTokenList(LIST *o);
+LIST *UniTokenListToList(UNI_TOKEN_LIST *t);
+bool UniIsSafeChar(wchar_t c);
+wchar_t *UniMakeCharArray(wchar_t c, UINT count);
+BUF *UniStrToBin(wchar_t *str);
+bool UniInStr(wchar_t *str, wchar_t *keyword);
+bool UniInStrEx(wchar_t *str, wchar_t *keyword, bool case_sensitive);
+
+#ifdef	OS_UNIX
+void GetCurrentCharSet(char *name, UINT size);
+UINT UnixCalcStrToUni(char *str);
+UINT UnixStrToUni(wchar_t *s, UINT size, char *str);
+UINT UnixCalcUniToStr(wchar_t *s);
+UINT UnixUniToStr(char *str, UINT size, wchar_t *s);
+void *IconvWideToStr();
+void *IconvStrToWide();
+int IconvFree(void *d);
+void *IconvWideToStrInternal();
+void *IconvStrToWideInternal();
+int IconvFreeInternal(void *d);
+#endif	// OS_UNIX
+
+#endif	// INTERNAT_H
+
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Kernel.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Kernel.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Kernel.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,1903 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Kernel.c
+// システムサービス処理ルーチン
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+#ifndef TM_YEAR_MAX
+#define TM_YEAR_MAX         2106
+#endif
+#ifndef TM_MON_MAX
+#define TM_MON_MAX          1
+#endif
+#ifndef TM_MDAY_MAX
+#define TM_MDAY_MAX         7
+#endif
+#ifndef TM_HOUR_MAX
+#define TM_HOUR_MAX         6
+#endif
+#ifndef TM_MIN_MAX
+#define TM_MIN_MAX          28
+#endif
+#ifndef TM_SEC_MAX
+#define TM_SEC_MAX          14
+#endif
+
+/* free mktime function
+   Copyright 1988, 1989 by David MacKenzie <djm@ai.mit.edu>
+   and Michael Haertel <mike@ai.mit.edu>
+   Unlimited distribution permitted provided this copyright notice is
+   retained and any functional modifications are prominently identified.  */
+#define ADJUST_TM(tm_member, tm_carry, modulus) \
+	if ((tm_member) < 0){ \
+		tm_carry -= (1 - ((tm_member)+1) / (modulus)); \
+		tm_member = (modulus-1) + (((tm_member)+1) % (modulus)); \
+	} else if ((tm_member) >= (modulus)) { \
+		tm_carry += (tm_member) / (modulus); \
+		tm_member = (tm_member) % (modulus); \
+	}
+#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
+#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)
+#define leapday(m, y) ((m) == 1 && leap (y))
+#define monthlen(m, y) (ydays[(m)+1] - ydays[m] + leapday (m, y))
+static int ydays[] =
+{
+	0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
+};
+
+
+static wchar_t *default_locale_str =
+L"- - $ : : $ Sun Mon Tue Wed Thu Fri Sat : : : $ (None)";
+
+static LOCALE current_locale;
+LOCK *tick_manual_lock = NULL;
+UINT g_zero = 0;
+
+// リアルタイムシステムタイマの取得
+UINT TickRealtime()
+{
+#if	defined(OS_WIN32) || defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC) || defined(CLOCK_HIGHRES)
+	return Tick() + 1;
+#else
+	return TickRealtimeManual() + 1;
+#endif
+}
+
+#ifndef	OS_WIN32
+
+static UINT64 last_manual_tick = 0;
+static UINT64 manual_tick_add_value = 0;
+
+// clock_gettime が無いシステム向け (MacOS X など)
+UINT TickRealtimeManual()
+{
+	UINT64 ret;
+	Lock(tick_manual_lock);
+	{
+		ret = TickGetRealtimeTickValue64();
+
+		if (last_manual_tick != 0 && (last_manual_tick > ret))
+		{
+			manual_tick_add_value += (last_manual_tick - ret);
+		}
+
+		last_manual_tick = ret;
+	}
+	Unlock(tick_manual_lock);
+
+	return (UINT)(ret + manual_tick_add_value);
+}
+
+// 現在時刻から適当な値を返す
+UINT64 TickGetRealtimeTickValue64()
+{
+	struct timeval tv;
+	struct timezone tz;
+	UINT64 ret;
+
+	memset(&tv, 0, sizeof(tv));
+	memset(&tz, 0, sizeof(tz));
+
+	gettimeofday(&tv, &tz);
+
+	ret = (UINT64)tv.tv_sec * 1000ULL + (UINT64)tv.tv_usec / 1000ULL;
+
+	return ret;
+}
+
+#endif	// OS_WIN32
+
+// ホームディレクトリを取得
+void GetHomeDirW(wchar_t *path, UINT size)
+{
+	// 引数チェック
+	if (path == NULL)
+	{
+		return;
+	}
+
+	if (GetEnvW(L"HOME", path, size) == false)
+	{
+		wchar_t drive[MAX_SIZE];
+		wchar_t hpath[MAX_SIZE];
+		if (GetEnvW(L"HOMEDRIVE", drive, sizeof(drive)) &&
+			GetEnvW(L"HOMEPATH", hpath, sizeof(hpath)))
+		{
+			UniFormat(path, sizeof(path), L"%s%s", drive, hpath);
+		}
+		else
+		{
+#ifdef	OS_WIN32
+			Win32GetCurrentDirW(path, size);
+#else	// OS_WIN32
+			UnixGetCurrentDirW(path, size);
+#endif	// OS_WIN32
+		}
+	}
+}
+void GetHomeDir(char *path, UINT size)
+{
+	// 引数チェック
+	if (path == NULL)
+	{
+		return;
+	}
+
+	if (GetEnv("HOME", path, size) == false)
+	{
+		char drive[MAX_SIZE];
+		char hpath[MAX_SIZE];
+		if (GetEnv("HOMEDRIVE", drive, sizeof(drive)) &&
+			GetEnv("HOMEPATH", hpath, sizeof(hpath)))
+		{
+			Format(path, sizeof(path), "%s%s", drive, hpath);
+		}
+		else
+		{
+#ifdef	OS_WIN32
+			Win32GetCurrentDir(path, size);
+#else	// OS_WIN32
+			UnixGetCurrentDir(path, size);
+#endif	// OS_WIN32
+		}
+	}
+}
+
+// 環境変数文字列を取得
+bool GetEnv(char *name, char *data, UINT size)
+{
+	char *ret;
+	// 引数チェック
+	if (name == NULL || data == NULL)
+	{
+		return false;
+	}
+
+	StrCpy(data, size, "");
+
+	ret = getenv(name);
+	if (ret == NULL)
+	{
+		return false;
+	}
+
+	StrCpy(data, size, ret);
+
+	return true;
+}
+bool GetEnvW(wchar_t *name, wchar_t *data, UINT size)
+{
+#ifdef	OS_WIN32
+	return GetEnvW_ForWin32(name, data, size);
+#else	// OS_WIN32
+	return GetEnvW_ForUnix(name, data, size);
+#endif	// OS_WIN32
+}
+
+#ifdef	OS_WIN32
+bool GetEnvW_ForWin32(wchar_t *name, wchar_t *data, UINT size)
+{
+	wchar_t *ret;
+	// 引数チェック
+	if (name == NULL || data == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		bool ret;
+		char *name_a = CopyUniToStr(name);
+		char data_a[MAX_SIZE];
+
+		ret = GetEnv(name_a, data_a, sizeof(data_a));
+
+		if (ret)
+		{
+			StrToUni(data, size, data_a);
+		}
+
+		Free(name_a);
+
+		return ret;
+	}
+
+	UniStrCpy(data, size, L"");
+
+	ret = _wgetenv(name);
+	if (ret == NULL)
+	{
+		return false;
+	}
+
+	UniStrCpy(data, size, ret);
+
+	return true;
+}
+
+#endif	// OS_WIN32
+
+#ifdef	OS_UNIX
+
+bool GetEnvW_ForUnix(wchar_t *name, wchar_t *data, UINT size)
+{
+	char *name_a;
+	bool ret;
+	char data_a[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL || data == NULL)
+	{
+		return false;
+	}
+
+	name_a = CopyUniToUtf(name);
+
+	ret = GetEnv(name_a, data_a, sizeof(data_a));
+
+	if (ret)
+	{
+		UtfToUni(data, size, data_a);
+	}
+
+	Free(name_a);
+
+	return ret;
+}
+
+#endif	// OS_UNIX
+
+// メモリ情報取得
+void GetMemInfo(MEMINFO *info)
+{
+	OSGetMemInfo(info);
+}
+
+// シングルインスタンスの開始
+INSTANCE *NewSingleInstance(char *instance_name)
+{
+	return NewSingleInstanceEx(instance_name, false);
+}
+INSTANCE *NewSingleInstanceEx(char *instance_name, bool user_local)
+{
+	char name[MAX_SIZE];
+	INSTANCE *ret;
+	void *data;
+
+	if (instance_name != NULL)
+	{
+		if (user_local == false)
+		{
+			HashInstanceName(name, sizeof(name), instance_name);
+		}
+		else
+		{
+			HashInstanceNameLocal(name, sizeof(name), instance_name);
+		}
+
+		data = OSNewSingleInstance(name);
+	}
+	else
+	{
+		data = OSNewSingleInstance(NULL);
+	}
+
+	if (data == NULL)
+	{
+		return NULL;
+	}
+
+	ret = ZeroMalloc(sizeof(INSTANCE));
+	if (instance_name != NULL)
+	{
+		ret->Name = CopyStr(instance_name);
+	}
+
+	ret->pData = data;
+
+	return ret;
+}
+
+// シングルインスタンスの解放
+void FreeSingleInstance(INSTANCE *inst)
+{
+	// 引数チェック
+	if (inst == NULL)
+	{
+		return;
+	}
+
+	OSFreeSingleInstance(inst->pData);
+
+	if (inst->Name != NULL)
+	{
+		Free(inst->Name);
+	}
+	Free(inst);
+}
+
+// インスタンス名をハッシュする
+void HashInstanceName(char *name, UINT size, char *instance_name)
+{
+	char tmp[MAX_SIZE];
+	UCHAR hash[SHA1_SIZE];
+	char key[11];
+	// 引数チェック
+	if (name == NULL || instance_name == NULL)
+	{
+		return;
+	}
+
+	StrCpy(tmp, sizeof(tmp), instance_name);
+	Trim(tmp);
+	StrUpper(tmp);
+
+	Hash(hash, tmp, StrLen(tmp), SHA1_SIZE);
+	BinToStr(key, sizeof(key), hash, 5);
+	key[10] = 0;
+
+	Format(name, size, "VPN-%s", key);
+
+	if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType))
+	{
+		if (GET_KETA(GetOsInfo()->OsType, 100) >= 2 ||
+			GetOsInfo()->OsType == OSTYPE_WINDOWS_NT_4_TERMINAL_SERVER)
+		{
+			StrCpy(tmp, sizeof(tmp), name);
+			Format(name, size, "Global\\%s", tmp);
+		}
+	}
+}
+void HashInstanceNameLocal(char *name, UINT size, char *instance_name)
+{
+	char tmp[MAX_SIZE];
+	UCHAR hash[SHA1_SIZE];
+	char key[11];
+	// 引数チェック
+	if (name == NULL || instance_name == NULL)
+	{
+		return;
+	}
+
+	StrCpy(tmp, sizeof(tmp), instance_name);
+	Trim(tmp);
+	StrUpper(tmp);
+
+	Hash(hash, tmp, StrLen(tmp), SHA1_SIZE);
+	BinToStr(key, sizeof(key), hash, 5);
+	key[10] = 0;
+
+	Format(name, size, "VPN-%s", key);
+
+	if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType))
+	{
+		if (GET_KETA(GetOsInfo()->OsType, 100) >= 2 ||
+			GetOsInfo()->OsType == OSTYPE_WINDOWS_NT_4_TERMINAL_SERVER)
+		{
+			StrCpy(tmp, sizeof(tmp), name);
+			Format(name, size, "Local\\%s", tmp);
+		}
+	}
+}
+
+// プロセスの起動
+bool Run(char *filename, char *arg, bool hide, bool wait)
+{
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return false;
+	}
+
+	return OSRun(filename, arg, hide, wait);
+}
+bool RunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait)
+{
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return false;
+	}
+
+	return OSRunW(filename, arg, hide, wait);
+}
+
+// 日付・時刻関係の関数
+void GetDateTimeStr64Uni(wchar_t *str, UINT size, UINT64 sec64)
+{
+	char tmp[MAX_SIZE];
+	if (str == NULL)
+	{
+		return;
+	}
+
+	GetDateTimeStr64(tmp, sizeof(tmp), sec64);
+	StrToUni(str, size, tmp);
+}
+void GetDateTimeStr64(char *str, UINT size, UINT64 sec64)
+{
+	SYSTEMTIME st;
+	UINT64ToSystem(&st, sec64);
+	GetDateTimeStr(str, size, &st);
+}
+void GetDateTimeStrMilli64(char *str, UINT size, UINT64 sec64)
+{
+	SYSTEMTIME st;
+	UINT64ToSystem(&st, sec64);
+	GetDateTimeStrMilli(str, size, &st);
+}
+void GetDateStr64(char *str, UINT size, UINT64 sec64)
+{
+	SYSTEMTIME st;
+	if (sec64 == 0)
+	{
+		StrCpy(str, size, "(Unknown)");
+		return;
+	}
+	UINT64ToSystem(&st, sec64);
+	GetDateStr(str, size, &st);
+}
+void GetDateTimeStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale)
+{
+	SYSTEMTIME st;
+	if (locale == NULL)
+	{
+		locale = &current_locale;
+	}
+	if (sec64 == 0 || SystemToLocal64(sec64) == 0 || LocalToSystem64(sec64) == 0)
+	{
+		UniStrCpy(str, size, locale->Unknown);
+		return;
+	}
+	UINT64ToSystem(&st, sec64);
+	GetDateTimeStrEx(str, size, &st, locale);
+}
+void GetTimeStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale)
+{
+	SYSTEMTIME st;
+	if (locale == NULL)
+	{
+		locale = &current_locale;
+	}
+	if (sec64 == 0 || SystemToLocal64(sec64) == 0 || LocalToSystem64(sec64) == 0)
+	{
+		UniStrCpy(str, size, locale->Unknown);
+		return;
+	}
+	UINT64ToSystem(&st, sec64);
+	GetTimeStrEx(str, size, &st, locale);
+}
+void GetDateStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale)
+{
+	SYSTEMTIME st;
+	if (locale == NULL)
+	{
+		locale = &current_locale;
+	}
+	if (sec64 == 0 || SystemToLocal64(sec64) == 0 || LocalToSystem64(sec64) == 0)
+	{
+		UniStrCpy(str, size, locale->Unknown);
+		return;
+	}
+	UINT64ToSystem(&st, sec64);
+	GetDateStrEx(str, size, &st, locale);
+}
+void GetTimeStrMilli64(char *str, UINT size, UINT64 sec64)
+{
+	SYSTEMTIME st;
+	if (sec64 == 0 || SystemToLocal64(sec64) == 0 || LocalToSystem64(sec64) == 0)
+	{
+		StrCpy(str, size, "(Unknown)");
+		return;
+	}
+	UINT64ToSystem(&st, sec64);
+	GetTimeStrMilli(str, size, &st);
+}
+void GetTimeStr64(char *str, UINT size, UINT64 sec64)
+{
+	SYSTEMTIME st;
+	if (sec64 == 0 || SystemToLocal64(sec64) == 0 || LocalToSystem64(sec64) == 0)
+	{
+		StrCpy(str, size, "(Unknown)");
+		return;
+	}
+	UINT64ToSystem(&st, sec64);
+	GetTimeStr(str, size, &st);
+}
+
+// 現在の POSIX 実装で使用しても安全な時刻に変換する
+UINT64 SafeTime64(UINT64 sec64)
+{
+	return MAKESURE(sec64, 0, 2115947647000ULL);
+}
+
+// スレッドプール
+static SK *thread_pool = NULL;
+static COUNTER *thread_count = NULL;
+
+// スレッドプールの初期化
+void InitThreading()
+{
+	thread_pool = NewSk();
+	thread_count = NewCounter();
+}
+
+// スレッドプールの解放
+void FreeThreading()
+{
+	while (true)
+	{
+		if (Count(thread_count) == 0)
+		{
+			break;
+		}
+
+		SleepThread(25);
+	}
+
+	while (true)
+	{
+		THREAD_POOL_DATA *pd;
+		THREAD *t = Pop(thread_pool);
+
+		if (t == NULL)
+		{
+			break;
+		}
+
+		pd = (THREAD_POOL_DATA *)t->param;
+
+		pd->ThreadProc = NULL;
+		Set(pd->Event);
+
+		WaitThreadInternal(t);
+
+		pd = (THREAD_POOL_DATA *)t->param;
+		ReleaseEvent(pd->Event);
+		ReleaseEvent(pd->InitFinishEvent);
+
+		ReleaseThreadInternal(t);
+
+		Free(pd);
+	}
+
+	ReleaseSk(thread_pool);
+
+	DeleteCounter(thread_count);
+	thread_count = NULL;
+}
+
+// スレッドプールプロシージャ
+void ThreadPoolProc(THREAD *t, void *param)
+{
+	THREAD_POOL_DATA *pd;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	pd = (THREAD_POOL_DATA *)param;
+
+	NoticeThreadInitInternal(t);
+
+	while (true)
+	{
+		THREAD *thread;
+		UINT i, num;
+		EVENT **ee;
+
+		// 次の仕事を待つ
+		Wait(pd->Event, INFINITE);
+
+		if (pd->ThreadProc == NULL)
+		{
+			// プールスレッドの動作停止
+			break;
+		}
+
+		thread = pd->Thread;
+		thread->ThreadId = ThreadId();
+
+		// 初期化完了
+		Set(pd->InitFinishEvent);
+
+		// スレッドプロシージャの実行
+		pd->ThreadProc(pd->Thread, thread->param);
+
+		thread->PoolHalting = true;
+
+		// 待機イベントリストを叩く
+		LockList(thread->PoolWaitList);
+		{
+			num = LIST_NUM(thread->PoolWaitList);
+			ee = ToArray(thread->PoolWaitList);
+
+			DeleteAll(thread->PoolWaitList);
+		}
+		UnlockList(thread->PoolWaitList);
+
+		for (i = 0;i < num;i++)
+		{
+			EVENT *e = ee[i];
+
+			Set(e);
+			ReleaseEvent(e);
+		}
+
+		Free(ee);
+
+		while (true)
+		{
+			if (Count(thread->ref->c) <= 1)
+			{
+				break;
+			}
+
+			Wait(thread->release_event, 256);
+		}
+
+		ReleaseThread(thread);
+
+#ifdef	OS_WIN32
+		// Win32 の場合: スレッドの優先順位を元に戻す
+		MsRestoreThreadPriority();
+#endif	// OS_WIN32
+
+		// スレッドプールに自分自身を登録する
+		LockSk(thread_pool);
+		{
+			Push(thread_pool, t);
+		}
+		UnlockSk(thread_pool);
+
+		Dec(thread_count);
+	}
+}
+
+// 何もしない
+UINT DoNothing()
+{
+	return g_zero;
+}
+
+// スレッド作成 (プール)
+THREAD *NewThread(THREAD_PROC *thread_proc, void *param)
+{
+	THREAD *host = NULL;
+	THREAD_POOL_DATA *pd = NULL;
+	THREAD *ret;
+	bool new_thread = false;
+	// 引数チェック
+	if (thread_proc == NULL)
+	{
+		return NULL;
+	}
+
+	if (IsTrackingEnabled() == false)
+	{
+		DoNothing();
+	}
+
+	Inc(thread_count);
+
+	LockSk(thread_pool);
+	{
+		// 現在プールに空いているスレッドがあるかどうか調べる
+		host = Pop(thread_pool);
+	}
+	UnlockSk(thread_pool);
+
+	if (host == NULL)
+	{
+		// 空いているスレッドが見つからなかったので新しいスレッドを作成する
+		pd = ZeroMalloc(sizeof(THREAD_POOL_DATA));
+		pd->Event = NewEvent();
+		pd->InitFinishEvent = NewEvent();
+		host = NewThreadInternal(ThreadPoolProc, pd);
+		WaitThreadInitInternal(host);
+
+		new_thread = true;
+	}
+	else
+	{
+		pd = (THREAD_POOL_DATA *)host->param;
+	}
+
+	// プールスレッドの作成
+	ret = ZeroMalloc(sizeof(THREAD));
+	ret->ref = NewRef();
+	ret->thread_proc = thread_proc;
+	ret->param = param;
+	ret->pData = NULL;
+	ret->init_finished_event = NewEvent();
+	ret->PoolThread = true;
+	ret->PoolWaitList = NewList(NULL);
+	ret->PoolHostThread = host;
+	ret->release_event = NewEvent();
+
+	// 実行
+	pd->ThreadProc = thread_proc;
+	pd->Thread = ret;
+	AddRef(ret->ref);
+
+	Set(pd->Event);
+
+	Wait(pd->InitFinishEvent, INFINITE);
+
+	return ret;
+}
+
+// スレッドのクリーンアップ (プール)
+void CleanupThread(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	ReleaseEvent(t->init_finished_event);
+	ReleaseEvent(t->release_event);
+	ReleaseList(t->PoolWaitList);
+
+	Free(t);
+}
+
+// スレッド解放 (プール)
+void ReleaseThread(THREAD *t)
+{
+	UINT ret;
+	EVENT *e;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	e = t->release_event;
+	if (e != NULL)
+	{
+		AddRef(e->ref);
+	}
+
+	ret = Release(t->ref);
+	Set(e);
+
+	ReleaseEvent(e);
+
+	if (ret == 0)
+	{
+		CleanupThread(t);
+	}
+}
+
+// スレッドの初期化完了を通知 (プール)
+void NoticeThreadInit(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	// 通知
+	Set(t->init_finished_event);
+}
+
+// スレッドの初期化完了を待機 (プール)
+void WaitThreadInit(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	// KS
+	KS_INC(KS_WAITFORTHREAD_COUNT);
+
+	// 待機
+	Wait(t->init_finished_event, INFINITE);
+}
+
+// スレッドの終了を待機 (プール)
+bool WaitThread(THREAD *t, UINT timeout)
+{
+	bool ret = false;
+	EVENT *e = NULL;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return false;
+	}
+
+	LockList(t->PoolWaitList);
+	{
+		if (t->PoolHalting)
+		{
+			// 既に停止済み
+			ret = true;
+		}
+		else
+		{
+			// 終了時通知イベントをリストに登録する
+			e = NewEvent();
+			AddRef(e->ref);
+			Insert(t->PoolWaitList, e);
+		}
+	}
+	UnlockList(t->PoolWaitList);
+
+	if (e != NULL)
+	{
+		// イベント待機
+		ret = Wait(e, timeout);
+
+		LockList(t->PoolWaitList);
+		{
+			if (Delete(t->PoolWaitList, e))
+			{
+				ReleaseEvent(e);
+			}
+		}
+		UnlockList(t->PoolWaitList);
+
+		ReleaseEvent(e);
+	}
+
+	return ret;
+}
+
+// スレッド ID の取得
+UINT ThreadId()
+{
+	return OSThreadId();
+}
+
+// スレッドの作成
+THREAD *NewThreadInternal(THREAD_PROC *thread_proc, void *param)
+{
+	THREAD *t;
+	UINT retry = 0;
+	// 引数チェック
+	if (thread_proc == NULL)
+	{
+		return NULL;
+	}
+
+	// スレッドオブジェクト初期化
+	t = ZeroMalloc(sizeof(THREAD));
+	t->init_finished_event = NewEvent();
+
+	t->param = param;
+	t->ref = NewRef();
+	t->thread_proc = thread_proc;
+
+	// OS がスレッドを初期化するまで待機
+	while (true)
+	{
+		if ((retry++) > 60)
+		{
+			printf("\n\n*** error: new thread create failed.\n\n");
+			AbortExit();
+		}
+		if (OSInitThread(t))
+		{
+			break;
+		}
+		SleepThread(500);
+	}
+
+	// KS
+	KS_INC(KS_NEWTHREAD_COUNT);
+
+	return t;
+}
+
+// スレッドの解放
+void ReleaseThreadInternal(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	if (Release(t->ref) == 0)
+	{
+		CleanupThreadInternal(t);
+	}
+}
+
+// スレッドのクリーンアップ
+void CleanupThreadInternal(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	// スレッドの解放
+	OSFreeThread(t);
+
+	// イベント解放
+	ReleaseEvent(t->init_finished_event);
+	// メモリ解放
+	Free(t);
+
+	// KS
+	KS_INC(KS_FREETHREAD_COUNT);
+}
+
+// スレッドの終了を待機する
+bool WaitThreadInternal(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return false;
+	}
+
+	return OSWaitThread(t);
+}
+
+// スレッドの初期化が完了したことを通知する
+void NoticeThreadInitInternal(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	// 通知
+	Set(t->init_finished_event);
+}
+
+// スレッドの初期化が完了するまで待機する
+void WaitThreadInitInternal(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	// KS
+	KS_INC(KS_WAITFORTHREAD_COUNT);
+
+	// 待機
+	Wait(t->init_finished_event, INFINITE);
+}
+
+// 日時文字列をロケール情報を使用して取得
+void GetDateTimeStrEx(wchar_t *str, UINT size, SYSTEMTIME *st, LOCALE *locale)
+{
+	wchar_t tmp1[MAX_SIZE];
+	wchar_t tmp2[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL || st == NULL)
+	{
+		return;
+	}
+
+	GetDateStrEx(tmp1, sizeof(tmp1), st, locale);
+	GetTimeStrEx(tmp2, sizeof(tmp2), st, locale);
+	UniFormat(str, size, L"%s %s", tmp1, tmp2);
+}
+
+// 時刻文字列をロケール情報を使用して取得
+void GetTimeStrEx(wchar_t *str, UINT size, SYSTEMTIME *st, LOCALE *locale)
+{
+	wchar_t *tag = L"%02u%s%02u%s%02u%s";
+	// 引数チェック
+	if (str == NULL || st == NULL)
+	{
+		return;
+	}
+
+	if (_GETLANG() == SE_LANG_JAPANESE || _GETLANG() == SE_LANG_CHINESE_ZH)
+	{
+		tag = L"%2u%s%2u%s%2u%s";
+	}
+
+	locale = (locale != NULL ? locale : &current_locale);
+	UniFormat(str, size,
+		tag,
+		st->wHour, locale->HourStr,
+		st->wMinute, locale->MinuteStr,
+		st->wSecond, locale->SecondStr);
+}
+
+// 日付文字列をロケール情報を使用して取得
+void GetDateStrEx(wchar_t *str, UINT size, SYSTEMTIME *st, LOCALE *locale)
+{
+	wchar_t *tag = L"%04u%s%02u%s%02u%s (%s)";
+	// 引数チェック
+	if (str == NULL || st == NULL)
+	{
+		return;
+	}
+
+	if (_GETLANG() == SE_LANG_JAPANESE || _GETLANG() == SE_LANG_CHINESE_ZH)
+	{
+		tag = L"%4u%s%2u%s%2u%s(%s)";
+	}
+
+	locale = (locale != NULL ? locale : &current_locale);
+	UniFormat(str, size,
+		tag,
+		st->wYear, locale->YearStr,
+		st->wMonth, locale->MonthStr,
+		st->wDay, locale->DayStr,
+		locale->DayOfWeek[st->wDayOfWeek]);
+}
+
+// 時刻文字列をミリ秒単位で取得 (例: 12:34:56.789)
+void GetTimeStrMilli(char *str, UINT size, SYSTEMTIME *st)
+{
+	// 引数チェック
+	if (st == NULL || str == NULL)
+	{
+		return;
+	}
+
+	Format(str, size, "%02u:%02u:%02u.%03u",
+		st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
+}
+
+// 時刻文字列を取得 (例: 12:34:56)
+void GetTimeStr(char *str, UINT size, SYSTEMTIME *st)
+{
+	// 引数チェック
+	if (str == NULL || st == NULL)
+	{
+		return;
+	}
+
+	Format(str, size, "%02u:%02u:%02u",
+		st->wHour, st->wMinute, st->wSecond);
+}
+
+// 日付文字列を取得 (例: 2004/07/23)
+void GetDateStr(char *str, UINT size, SYSTEMTIME *st)
+{
+	// 引数チェック
+	if (str == NULL || st == NULL)
+	{
+		return;
+	}
+
+	Format(str, size, "%04u-%02u-%02u",
+		st->wYear, st->wMonth, st->wDay);
+}
+
+// 日時文字列を取得 (例: 2004/07/23 12:34:56)
+void GetDateTimeStr(char *str, UINT size, SYSTEMTIME *st)
+{
+	// 引数チェック
+	if (str == NULL || st == NULL)
+	{
+		return;
+	}
+
+	Format(str, size, "%04u-%02u-%02u %02u:%02u:%02u",
+		st->wYear, st->wMonth, st->wDay,
+		st->wHour, st->wMinute, st->wSecond);
+}
+
+// 日時文字列をミリ秒単位で取得 (例: 2004/07/23 12:34:56.789)
+void GetDateTimeStrMilli(char *str, UINT size, SYSTEMTIME *st)
+{
+	// 引数チェック
+	if (str == NULL || st == NULL)
+	{
+		return;
+	}
+
+	Format(str, size, "%04u-%02u-%02u %02u:%02u:%02u.%03u",
+		st->wYear, st->wMonth, st->wDay,
+		st->wHour, st->wMinute, st->wSecond,
+		st->wMilliseconds);
+}
+
+// 時間文字列の取得
+void GetSpanStr(char *str, UINT size, UINT64 sec64)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	StrCpy(tmp, sizeof(tmp), "");
+	if (sec64 >= (UINT64)(1000 * 3600 * 24))
+	{
+		Format(tmp, sizeof(tmp), "%u:", (UINT)(sec64 / (UINT64)(1000 * 3600 * 24)));
+	}
+
+	Format(tmp, sizeof(tmp), "%s%02u:%02u:%02u", tmp,
+		(UINT)(sec64 % (UINT64)(1000 * 60 * 60 * 24)) / (1000 * 60 * 60),
+		(UINT)(sec64 % (UINT64)(1000 * 60 * 60)) / (1000 * 60),
+		(UINT)(sec64 % (UINT64)(1000 * 60)) / 1000);
+
+	Trim(tmp);
+	StrCpy(str, size, tmp);
+}
+
+// 時間文字列の取得 (ミリ秒単位)
+void GetSpanStrMilli(char *str, UINT size, UINT64 sec64)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	StrCpy(tmp, sizeof(tmp), "");
+	if (sec64 >= (UINT64)(1000 * 3600 * 24))
+	{
+		Format(tmp, sizeof(tmp), "%u:", (UINT)(sec64 / (UINT64)(1000 * 3600 * 24)));
+	}
+
+	Format(tmp, sizeof(tmp), "%s%02u:%02u:%02u.%03u", tmp,
+		(UINT)(sec64 % (UINT64)(1000 * 60 * 60 * 24)) / (1000 * 60 * 60),
+		(UINT)(sec64 % (UINT64)(1000 * 60 * 60)) / (1000 * 60),
+		(UINT)(sec64 % (UINT64)(1000 * 60)) / 1000,
+		(UINT)(sec64 % (UINT64)(1000)));
+
+	Trim(tmp);
+	StrCpy(str, size, tmp);
+}
+
+// 時間文字列の取得 (拡張)
+void GetSpanStrEx(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale)
+{
+	wchar_t tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	locale = (locale != NULL ? locale : &current_locale);
+
+	UniStrCpy(tmp, sizeof(tmp), L"");
+	if (sec64 >= (UINT64)(1000 * 3600 * 24))
+	{
+		UniFormat(tmp, sizeof(tmp), L"%u%s ", (UINT)(sec64 / (UINT64)(1000 * 3600 * 24)),
+			locale->SpanDay);
+	}
+
+	UniFormat(tmp, sizeof(tmp), L"%s%u%s %02u%s %02u%s", tmp,
+		(UINT)(sec64 % (UINT64)(1000 * 60 * 60 * 24)) / (1000 * 60 * 60),
+		locale->SpanHour,
+		(UINT)(sec64 % (UINT64)(1000 * 60 * 60)) / (1000 * 60),
+		locale->SpanMinute,
+		(UINT)(sec64 % (UINT64)(1000 * 60)) / 1000,
+		locale->SpanSecond);
+
+	UniTrim(tmp);
+	UniStrCpy(str, size, tmp);
+}
+
+// 現在のロケール情報を取得
+void GetCurrentLocale(LOCALE *locale)
+{
+	// 引数チェック
+	if (locale == NULL)
+	{
+		return;
+	}
+
+	Copy(locale, &current_locale, sizeof(LOCALE));
+}
+
+// ロケール情報を設定
+void SetLocale(wchar_t *str)
+{
+	wchar_t *set_locale_str;
+	LOCALE tmp;
+
+	if (str != NULL)
+	{
+		set_locale_str = str;
+	}
+	else
+	{
+		set_locale_str = default_locale_str;
+	}
+
+	if (LoadLocale(&tmp, set_locale_str) == false)
+	{
+		if (LoadLocale(&tmp, default_locale_str) == false)
+		{
+			return;
+		}
+	}
+
+	Copy(&current_locale, &tmp, sizeof(LOCALE));
+}
+
+#define	COPY_LOCALE_STR(dest, size, src)	UniStrCpy(dest, size, UniStrCmp(src, L"$") == 0 ? L"" : src)
+
+// ロケール情報の読み込み
+bool LoadLocale(LOCALE *locale, wchar_t *str)
+{
+	UNI_TOKEN_LIST *tokens;
+	UINT i;
+	// 引数チェック
+	if (locale == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	// トークンの解析
+	tokens = UniParseToken(str, L" ");
+	if (tokens->NumTokens != 18)
+	{
+		UniFreeToken(tokens);
+		return false;
+	}
+
+	// 構造体にセット
+	Zero(locale, sizeof(LOCALE));
+	COPY_LOCALE_STR(locale->YearStr, sizeof(locale->YearStr), tokens->Token[0]);
+	COPY_LOCALE_STR(locale->MonthStr, sizeof(locale->MonthStr), tokens->Token[1]);
+	COPY_LOCALE_STR(locale->DayStr, sizeof(locale->DayStr), tokens->Token[2]);
+	COPY_LOCALE_STR(locale->HourStr, sizeof(locale->HourStr), tokens->Token[3]);
+	COPY_LOCALE_STR(locale->MinuteStr, sizeof(locale->MinuteStr), tokens->Token[4]);
+	COPY_LOCALE_STR(locale->SecondStr, sizeof(locale->SecondStr), tokens->Token[5]);
+
+	for (i = 0;i < 7;i++)
+	{
+		COPY_LOCALE_STR(locale->DayOfWeek[i], sizeof(locale->DayOfWeek[i]),
+			tokens->Token[6 + i]);
+	}
+
+	COPY_LOCALE_STR(locale->SpanDay, sizeof(locale->SpanDay), tokens->Token[13]);
+	COPY_LOCALE_STR(locale->SpanHour, sizeof(locale->SpanHour), tokens->Token[14]);
+	COPY_LOCALE_STR(locale->SpanMinute, sizeof(locale->SpanMinute), tokens->Token[15]);
+	COPY_LOCALE_STR(locale->SpanSecond, sizeof(locale->SpanSecond), tokens->Token[16]);
+
+	COPY_LOCALE_STR(locale->Unknown, sizeof(locale->Unknown), tokens->Token[17]);
+
+	UniFreeToken(tokens);
+	return true;
+}
+
+// tm を SYSTEMTIME に変換
+void TmToSystem(SYSTEMTIME *st, struct tm *t)
+{
+	struct tm tmp;
+	// 引数チェック
+	if (st == NULL || t == NULL)
+	{
+		return;
+	}
+
+	Copy(&tmp, t, sizeof(struct tm));
+	NormalizeTm(&tmp);
+
+	Zero(st, sizeof(SYSTEMTIME));
+	st->wYear = MAKESURE(tmp.tm_year + 1900, 1970, 2037);
+	st->wMonth = MAKESURE(tmp.tm_mon + 1, 1, 12);
+	st->wDay = MAKESURE(tmp.tm_mday, 1, 31);
+	st->wDayOfWeek = MAKESURE(tmp.tm_wday, 0, 6);
+	st->wHour = MAKESURE(tmp.tm_hour, 0, 23);
+	st->wMinute = MAKESURE(tmp.tm_min, 0, 59);
+	st->wSecond = MAKESURE(tmp.tm_sec, 0, 59);
+	st->wMilliseconds = 0;
+}
+
+// SYSTEMTIME を tm に変換
+void SystemToTm(struct tm *t, SYSTEMTIME *st)
+{
+	// 引数チェック
+	if (t == NULL || st == NULL)
+	{
+		return;
+	}
+
+	Zero(t, sizeof(struct tm));
+	t->tm_year = MAKESURE(st->wYear, 1970, 2037) - 1900;
+	t->tm_mon = MAKESURE(st->wMonth, 1, 12) - 1;
+	t->tm_mday = MAKESURE(st->wDay, 1, 31);
+	t->tm_hour = MAKESURE(st->wHour, 0, 23);
+	t->tm_min = MAKESURE(st->wMinute, 0, 59);
+	t->tm_sec = MAKESURE(st->wSecond, 0, 59);
+
+	t->tm_isdst = -1;
+	NormalizeTm(t);
+}
+
+// time_t を SYSTEMTIME に変換
+void TimeToSystem(SYSTEMTIME *st, time_t t)
+{
+	struct tm tmp;
+	// 引数チェック
+	if (st == NULL)
+	{
+		return;
+	}
+
+	TimeToTm(&tmp, t);
+	TmToSystem(st, &tmp);
+}
+
+// SYSTEMTIME を time_t に変換
+time_t SystemToTime(SYSTEMTIME *st)
+{
+	struct tm t;
+	// 引数チェック
+	if (st == NULL)
+	{
+		return 0;
+	}
+
+	SystemToTm(&t, st);
+	return TmToTime(&t);
+}
+
+// tm を time_t に変換
+time_t TmToTime(struct tm *t)
+{
+	time_t tmp;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return 0;
+	}
+
+	tmp = c_mkgmtime(t);
+	if (tmp == (time_t)-1)
+	{
+		return 0;
+	}
+	return tmp;
+}
+
+// time_t を tm に変換
+void TimeToTm(struct tm *t, time_t time)
+{
+	struct tm *ret;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+#ifndef	OS_UNIX
+	ret = gmtime(&time);
+#else	// OS_UNIX
+	ret = malloc(sizeof(struct tm));
+	memset(ret, 0, sizeof(ret));
+	gmtime_r(&time, ret);
+#endif	// OS_UNIX
+
+	if (ret == NULL)
+	{
+		Zero(t, sizeof(struct tm));
+	}
+	else
+	{
+		Copy(t, ret, sizeof(struct tm));
+	}
+
+#ifdef	OS_UNIX
+	free(ret);
+#endif	// OS_UNIX
+}
+
+// tm を正規化
+void NormalizeTm(struct tm *t)
+{
+	struct tm *ret;
+	time_t tmp;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	tmp = c_mkgmtime(t);
+	if (tmp == (time_t)-1)
+	{
+		return;
+	}
+
+#ifndef	OS_UNIX
+	ret = gmtime(&tmp);
+#else	// OS_UNIX
+	ret = malloc(sizeof(struct tm));
+	memset(ret, 0, sizeof(ret));
+	gmtime_r(&tmp, ret);
+#endif	// OS_UNIX
+
+	if (ret == NULL)
+	{
+		Zero(t, sizeof(struct tm));
+	}
+	else
+	{
+		Copy(t, ret, sizeof(struct tm));
+	}
+
+#ifdef	OS_UNIX
+	free(ret);
+#endif	// OS_UNIX
+}
+
+// SYSTEMTIME を正規化
+void NormalizeSystem(SYSTEMTIME *st)
+{
+	UINT64 sec64;
+	// 引数チェック
+	if (st == NULL)
+	{
+		return;
+	}
+
+	sec64 = SystemToUINT64(st);
+	UINT64ToSystem(st, sec64);
+}
+
+// 64bit ローカル時刻をシステム時刻に変換
+UINT64 LocalToSystem64(UINT64 t)
+{
+	SYSTEMTIME st;
+	UINT64ToSystem(&st, t);
+	LocalToSystem(&st, &st);
+	return SystemToUINT64(&st);
+}
+
+// 64bit システム時刻をローカル時刻に変換
+UINT64 SystemToLocal64(UINT64 t)
+{
+	SYSTEMTIME st;
+	UINT64ToSystem(&st, t);
+	SystemToLocal(&st, &st);
+	return SystemToUINT64(&st);
+}
+
+// ローカル時刻をシステム時刻に変換
+void LocalToSystem(SYSTEMTIME *system, SYSTEMTIME *local)
+{
+	UINT64 sec64;
+	// 引数チェック
+	if (local == NULL || system == NULL)
+	{
+		return;
+	}
+
+	sec64 = (UINT64)((INT64)SystemToUINT64(local) - GetTimeDiffEx(local, true));
+	UINT64ToSystem(system, sec64);
+}
+
+// システム時刻をローカル時刻に変換
+void SystemToLocal(SYSTEMTIME *local, SYSTEMTIME *system)
+{
+	UINT64 sec64;
+	// 引数チェック
+	if (local == NULL || system == NULL)
+	{
+		return;
+	}
+
+	sec64 = (UINT64)((INT64)SystemToUINT64(system) + GetTimeDiffEx(system, false));
+	UINT64ToSystem(local, sec64);
+}
+
+// 指定時刻をベースにしてシステム時刻とローカル時刻との間の時差を取得
+INT64 GetTimeDiffEx(SYSTEMTIME *basetime, bool local_time)
+{
+	time_t tmp;
+	struct tm t1, t2;
+	SYSTEMTIME snow;
+	struct tm now;
+	SYSTEMTIME s1, s2;
+	INT64 ret;
+
+	Copy(&snow, basetime, sizeof(SYSTEMTIME));
+
+	SystemToTm(&now, &snow);
+	if (local_time == false)
+	{
+		tmp = c_mkgmtime(&now);
+	}
+	else
+	{
+		tmp = mktime(&now);
+	}
+
+	if (tmp == (time_t)-1)
+	{
+		return 0;
+	}
+
+	Copy(&t1, localtime(&tmp), sizeof(struct tm));
+	Copy(&t2, gmtime(&tmp), sizeof(struct tm));
+	TmToSystem(&s1, &t1);
+	TmToSystem(&s2, &t2);
+
+	ret = (INT)SystemToUINT64(&s1) - (INT)SystemToUINT64(&s2);
+
+	return ret;
+}
+
+// システム時刻とローカル時刻との間の時差を取得
+INT64 GetTimeDiff()
+{
+	time_t tmp;
+	struct tm t1, t2;
+	SYSTEMTIME snow;
+	struct tm now;
+	SYSTEMTIME s1, s2;
+	INT64 ret;
+
+	static INT64 cache = INFINITE;
+
+	if (cache != INFINITE)
+	{
+		// 1 度測定したらキャッシュデータを返す
+		return cache;
+	}
+
+	SystemTime(&snow);
+	SystemToTm(&now, &snow);
+	tmp = c_mkgmtime(&now);
+	if (tmp == (time_t)-1)
+	{
+		return 0;
+	}
+
+	Copy(&t1, localtime(&tmp), sizeof(struct tm));
+	Copy(&t2, gmtime(&tmp), sizeof(struct tm));
+	TmToSystem(&s1, &t1);
+	TmToSystem(&s2, &t2);
+
+	cache = ret = (INT)SystemToUINT64(&s1) - (INT)SystemToUINT64(&s2);
+
+	return ret;
+}
+
+// UINT64 を SYSTEMTIME に変換
+void UINT64ToSystem(SYSTEMTIME *st, UINT64 sec64)
+{
+	UINT64 tmp64;
+	UINT sec, millisec;
+	time_t time;
+	// 引数チェック
+	if (st == NULL)
+	{
+		return;
+	}
+
+	sec64 = SafeTime64(sec64 + 32400000ULL);
+	tmp64 = sec64 / (UINT64)1000;
+	millisec = (UINT)(sec64 - tmp64 * (UINT64)1000);
+	sec = (UINT)tmp64;
+	time = (time_t)sec;
+	TimeToSystem(st, time);
+	st->wMilliseconds = (WORD)millisec;
+}
+
+// SYSTEMTIME を UINT64 に変換
+UINT64 SystemToUINT64(SYSTEMTIME *st)
+{
+	UINT64 sec64;
+	time_t time;
+	// 引数チェック
+	if (st == NULL)
+	{
+		return 0;
+	}
+
+	time = SystemToTime(st);
+	sec64 = (UINT64)time * (UINT64)1000;
+	sec64 += st->wMilliseconds;
+
+	return sec64 - 32400000ULL;
+}
+
+// ローカル時刻を UINT64 で取得
+UINT64 LocalTime64()
+{
+	SYSTEMTIME s;
+	LocalTime(&s);
+	return SystemToUINT64(&s);
+}
+
+// システム時刻を UINT64 で取得
+UINT64 SystemTime64()
+{
+	SYSTEMTIME s;
+	SystemTime(&s);
+	return SystemToUINT64(&s);
+}
+
+// ローカル時刻の取得
+void LocalTime(SYSTEMTIME *st)
+{
+	SYSTEMTIME tmp;
+	// 引数チェック
+	if (st == NULL)
+	{
+		return;
+	}
+
+	SystemTime(&tmp);
+	SystemToLocal(st, &tmp);
+}
+
+// システム時刻の取得
+void SystemTime(SYSTEMTIME *st)
+{
+	// 引数チェック
+	if (st == NULL)
+	{
+		return;
+	}
+
+	OSGetSystemTime(st);
+
+	// KS
+	KS_INC(KS_GETTIME_COUNT);
+}
+
+/* free mktime function
+   Copyright 1988, 1989 by David MacKenzie <djm@ai.mit.edu>
+   and Michael Haertel <mike@ai.mit.edu>
+   Unlimited distribution permitted provided this copyright notice is
+   retained and any functional modifications are prominently identified.  */
+time_t c_mkgmtime(struct tm *tm)
+{
+	int years, months, days, hours, minutes, seconds;
+
+	years = tm->tm_year + 1900;   /* year - 1900 -> year */
+	months = tm->tm_mon;          /* 0..11 */
+	days = tm->tm_mday - 1;       /* 1..31 -> 0..30 */
+	hours = tm->tm_hour;          /* 0..23 */
+	minutes = tm->tm_min;         /* 0..59 */
+	seconds = tm->tm_sec;         /* 0..61 in ANSI C. */
+
+	ADJUST_TM(seconds, minutes, 60);
+	ADJUST_TM(minutes, hours, 60);
+	ADJUST_TM(hours, days, 24);
+	ADJUST_TM(months, years, 12);
+	if (days < 0)
+		do {
+			if (--months < 0) {
+				--years;
+				months = 11;
+			}
+			days += monthlen(months, years);
+		} while (days < 0);
+	else
+		while (days >= monthlen(months, years)) {
+			days -= monthlen(months, years);
+			if (++months >= 12) {
+				++years;
+				months = 0;
+			}
+		}
+
+		/* Restore adjusted values in tm structure */
+		tm->tm_year = years - 1900;
+		tm->tm_mon = months;
+		tm->tm_mday = days + 1;
+		tm->tm_hour = hours;
+		tm->tm_min = minutes;
+		tm->tm_sec = seconds;
+
+		/* Set `days' to the number of days into the year. */
+		days += ydays[months] + (months > 1 && leap (years));
+		tm->tm_yday = days;
+
+		/* Now calculate `days' to the number of days since Jan 1, 1970. */
+		days = (unsigned)days + 365 * (unsigned)(years - 1970) +
+			(unsigned)(nleap (years));
+		tm->tm_wday = ((unsigned)days + 4) % 7; /* Jan 1, 1970 was Thursday. */
+		tm->tm_isdst = 0;
+
+		if (years < 1970)
+			return (time_t)-1;
+
+#if (defined(TM_YEAR_MAX) && defined(TM_MON_MAX) && defined(TM_MDAY_MAX))
+#if (defined(TM_HOUR_MAX) && defined(TM_MIN_MAX) && defined(TM_SEC_MAX))
+		if (years > TM_YEAR_MAX ||
+			(years == TM_YEAR_MAX &&
+			(tm->tm_yday > ydays[TM_MON_MAX] + (TM_MDAY_MAX - 1) +
+			(TM_MON_MAX > 1 && leap (TM_YEAR_MAX)) ||
+			(tm->tm_yday == ydays[TM_MON_MAX] + (TM_MDAY_MAX - 1) +
+			(TM_MON_MAX > 1 && leap (TM_YEAR_MAX)) &&
+			(hours > TM_HOUR_MAX ||
+			(hours == TM_HOUR_MAX &&
+			(minutes > TM_MIN_MAX ||
+			(minutes == TM_MIN_MAX && seconds > TM_SEC_MAX) )))))))
+			return (time_t)-1;
+#endif
+#endif
+
+		return (time_t)(86400L * (unsigned long)(unsigned)days +
+			3600L * (unsigned long)hours +
+			(unsigned long)(60 * minutes + seconds));
+}
+
+// システムタイマの取得
+UINT Tick()
+{
+	// KS
+	KS_INC(KS_GETTICK_COUNT);
+	return OSGetTick();
+}
+
+// スレッドのスリープ
+void SleepThread(UINT time)
+{
+	// KS
+	KS_INC(KS_SLEEPTHREAD_COUNT);
+
+	OSSleep(time);
+}
+
+// イールド
+void YieldCpu()
+{
+	OSYield();
+}
+
+// システム停止 (異常終了)
+void AbortExit()
+{
+#ifdef	OS_WIN32
+	_exit(1);
+#else	// OS_WIN32
+
+#ifdef	RLIMIT_CORE
+	UnixSetResourceLimit(RLIMIT_CORE, 0);
+#endif	// RLIMIT_CORE
+
+	abort();
+#endif	// OS_WIN32
+}
+
+
+void AbortExitEx(char *msg)
+{
+	FILE *f;
+	// 引数チェック
+	if (msg == NULL)
+	{
+		msg = "Unknown Error";
+	}
+
+	f = fopen("abort_error_log.txt", "w");
+	if (f != NULL)
+	{
+		fwrite(msg, 1, strlen(msg), f);
+		fclose(f);
+	}
+
+	fputs("Fatal Error: ", stdout);
+	fputs(msg, stdout);
+	fputs("\r\n", stdout);
+
+#ifdef	OS_WIN32
+	_exit(1);
+#else	// OS_WIN32
+
+#ifdef	RLIMIT_CORE
+	UnixSetResourceLimit(RLIMIT_CORE, 0);
+#endif	// RLIMIT_CORE
+
+	abort();
+#endif	// OS_WIN32
+}
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Kernel.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Kernel.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Kernel.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,227 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+#ifndef	KERNEL_H
+#define	KERNEL_H
+
+// メモリ使用情報
+struct MEMINFO
+{
+	UINT64 TotalMemory;
+	UINT64 UsedMemory;
+	UINT64 FreeMemory;
+	UINT64 TotalPhys;
+	UINT64 UsedPhys;
+	UINT64 FreePhys;
+};
+
+// ロケール情報
+struct LOCALE
+{
+	wchar_t YearStr[16], MonthStr[16], DayStr[16];
+	wchar_t HourStr[16], MinuteStr[16], SecondStr[16];
+	wchar_t DayOfWeek[7][16];
+	wchar_t SpanDay[16], SpanHour[16], SpanMinute[16], SpanSecond[16];
+	wchar_t Unknown[32];
+};
+
+
+// スレッドプロシージャ
+typedef void (THREAD_PROC)(THREAD *thread, void *param);
+
+// スレッド
+struct THREAD
+{
+	REF *ref;
+	THREAD_PROC *thread_proc;
+	void *param;
+	void *pData;
+	EVENT *init_finished_event;
+	void *AppData1, *AppData2, *AppData3;
+	UINT AppInt1, AppInt2, AppInt3;
+	UINT ThreadId;
+	bool PoolThread;
+	THREAD *PoolHostThread;
+	LIST *PoolWaitList;						// スレッド停止待機リスト
+	volatile bool PoolHalting;				// スレッド停止中
+	EVENT *release_event;
+};
+
+// スレッドプールデータ
+struct THREAD_POOL_DATA
+{
+	EVENT *Event;						// 待機イベント
+	EVENT *InitFinishEvent;				// 初期化完了イベント
+	THREAD *Thread;						// 現在割り当てられているスレッド
+	THREAD_PROC *ThreadProc;			// 現在割り当てられているスレッドプロシージャ
+};
+
+// インスタンス
+struct INSTANCE
+{
+	char *Name;							// 名前
+	void *pData;						// データ
+};
+
+// 関数プロトタイプ
+void SleepThread(UINT time);
+THREAD *NewThreadInternal(THREAD_PROC *thread_proc, void *param);
+void ReleaseThreadInternal(THREAD *t);
+void CleanupThreadInternal(THREAD *t);
+void NoticeThreadInitInternal(THREAD *t);
+void WaitThreadInitInternal(THREAD *t);
+bool WaitThreadInternal(THREAD *t);
+THREAD *NewThread(THREAD_PROC *thread_proc, void *param);
+void ReleaseThread(THREAD *t);
+void CleanupThread(THREAD *t);
+void NoticeThreadInit(THREAD *t);
+void WaitThreadInit(THREAD *t);
+bool WaitThread(THREAD *t, UINT timeout);
+void InitThreading();
+void FreeThreading();
+void ThreadPoolProc(THREAD *t, void *param);
+
+time_t c_mkgmtime(struct tm *tm);
+void TmToSystem(SYSTEMTIME *st, struct tm *t);
+void SystemToTm(struct tm *t, SYSTEMTIME *st);
+void TimeToSystem(SYSTEMTIME *st, time_t t);
+time_t SystemToTime(SYSTEMTIME *st);
+time_t TmToTime(struct tm *t);
+void TimeToTm(struct tm *t, time_t time);
+void NormalizeTm(struct tm *t);
+void NormalizeSystem(SYSTEMTIME *st);
+void LocalToSystem(SYSTEMTIME *system, SYSTEMTIME *local);
+void SystemToLocal(SYSTEMTIME *local, SYSTEMTIME *system);
+INT64 GetTimeDiffEx(SYSTEMTIME *basetime, bool local_time);
+void UINT64ToSystem(SYSTEMTIME *st, UINT64 sec64);
+UINT64 SystemToUINT64(SYSTEMTIME *st);
+UINT64 LocalTime64();
+UINT64 SystemTime64();
+void LocalTime(SYSTEMTIME *st);
+void SystemTime(SYSTEMTIME *st);
+void SetLocale(wchar_t *str);
+bool LoadLocale(LOCALE *locale, wchar_t *str);
+void GetCurrentLocale(LOCALE *locale);
+void GetDateTimeStr(char *str, UINT size, SYSTEMTIME *st);
+void GetDateTimeStrMilli(char *str, UINT size, SYSTEMTIME *st);
+void GetDateStr(char *str, UINT size, SYSTEMTIME *st);
+void GetDateTimeStrEx(wchar_t *str, UINT size, SYSTEMTIME *st, LOCALE *locale);
+void GetTimeStrEx(wchar_t *str, UINT size, SYSTEMTIME *st, LOCALE *locale);
+void GetDateStrEx(wchar_t *str, UINT size, SYSTEMTIME *st, LOCALE *locale);
+void GetTimeStrMilli(char *str, UINT size, SYSTEMTIME *st);
+void GetTimeStr(char *str, UINT size, SYSTEMTIME *st);
+UINT Tick();
+UINT TickRealtime();
+UINT TickRealtimeManual();
+UINT64 TickGetRealtimeTickValue64();
+UINT64 SystemToLocal64(UINT64 t);
+UINT64 LocalToSystem64(UINT64 t);
+UINT ThreadId();
+void GetDateTimeStr64(char *str, UINT size, UINT64 sec64);
+void GetDateTimeStr64Uni(wchar_t *str, UINT size, UINT64 sec64);
+void GetDateTimeStrMilli64(char *str, UINT size, UINT64 sec64);
+void GetDateStr64(char *str, UINT size, UINT64 sec64);
+void GetDateTimeStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale);
+void GetTimeStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale);
+void GetDateStrEx64(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale);
+void GetTimeStrMilli64(char *str, UINT size, UINT64 sec64);
+void GetTimeStr64(char *str, UINT size, UINT64 sec64);
+UINT64 SafeTime64(UINT64 sec64);
+bool Run(char *filename, char *arg, bool hide, bool wait);
+bool RunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait);
+void HashInstanceName(char *name, UINT size, char *instance_name);
+void HashInstanceNameLocal(char *name, UINT size, char *instance_name);
+INSTANCE *NewSingleInstance(char *instance_name);
+INSTANCE *NewSingleInstanceEx(char *instance_name, bool user_local);
+void FreeSingleInstance(INSTANCE *inst);
+void GetSpanStr(char *str, UINT size, UINT64 sec64);
+void GetSpanStrEx(wchar_t *str, UINT size, UINT64 sec64, LOCALE *locale);
+void GetSpanStrMilli(char *str, UINT size, UINT64 sec64);
+void GetMemInfo(MEMINFO *info);
+bool GetEnv(char *name, char *data, UINT size);
+bool GetEnvW(wchar_t *name, wchar_t *data, UINT size);
+bool GetEnvW_ForWin32(wchar_t *name, wchar_t *data, UINT size);
+bool GetEnvW_ForUnix(wchar_t *name, wchar_t *data, UINT size);
+void GetHomeDir(char *path, UINT size);
+void GetHomeDirW(wchar_t *path, UINT size);
+void AbortExit();
+void AbortExitEx(char *msg);
+void YieldCpu();
+UINT DoNothing();
+
+#endif	// KERNEL_H
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/MayaType.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/MayaType.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/MayaType.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,432 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// MayaType.h
+// Mayaqua Kernel 型宣言ヘッダファイル
+
+#ifndef	MAYATYPE_H
+#define	MAYATYPE_H
+
+// windows.h ヘッダが include されているかどうかをチェック
+#ifndef	WINDOWS_H
+#ifdef	_WINDOWS_
+#define	WINDOWS_H
+#endif	// _WINDOWS_
+#endif	// WINDOWS_H
+
+
+#if	!defined(ENCRYPT_C) && !defined(HAM_C)
+// OpenSSL が使用する構造体
+typedef struct x509_st X509;
+typedef struct evp_pkey_st EVP_PKEY;
+typedef struct bio_st BIO;
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
+typedef struct X509_req_st X509_REQ;
+typedef struct PKCS12 PKCS12;
+typedef struct bignum_st BIGNUM;
+typedef struct x509_crl_st X509_CRL;
+#endif	// ENCRYPT_C
+
+// 
+// 定数
+// 
+
+// 標準のバッファサイズ
+#define	STD_SIZE			512
+#define	MAX_SIZE			512
+#define	BUF_SIZE			512
+
+// 対応 Windows OS 一覧
+#define	SUPPORTED_WINDOWS_LIST		"Windows 98 / 98 SE / ME / NT 4.0 SP6a / 2000 SP4 / XP SP2, SP3 / Server 2003 SP2 / SBS 2003 SP2 / Storage Server 2003 SP2 / Vista SP1, SP2 / Server 2008 SP1, SP2 / Storage Server 2008 SP1, SP2 / Home Server / 7 / Server 2008 R2"
+
+// 無限
+#ifndef	WINDOWS_H
+#define	INFINITE			(0xFFFFFFFF)
+#endif
+
+
+#define	SRC_NAME			__FILE__	// ソースコードのファイル名
+#define	SRC_LINE			__LINE__	// ソースコード中の行番号
+
+// 最大パスサイズ
+#ifndef	WINDOWS_H
+#define	MAX_PATH			260
+#endif	// WINDOWS_H
+
+// シークの種類
+#ifndef	FILE_BEGIN
+#define	FILE_BEGIN	SEEK_SET
+#endif	// FILE_BEGIN
+#ifndef	FILE_END
+#define	FILE_END	SEEK_END
+#endif	// FILE_END
+#ifndef	FILE_CURRENT
+#define	FILE_CURRENT	SEEK_CUR
+#endif	// FILE_CURRENT
+
+#ifndef	INVALID_SOCKET
+#define	INVALID_SOCKET		(-1)
+#endif	// INVALID_SOCKET
+
+#ifndef	SOCKET_ERROR
+#define	SOCKET_ERROR		(-1)
+#endif	//SOCKET_ERROR
+
+// 比較関数
+typedef int (COMPARE)(void *p1, void *p2);
+
+// 
+// マクロ
+
+
+#ifdef	MAX
+#undef	MAX
+#endif	// MAX
+
+#ifdef	MIN
+#undef	MIN
+#endif	// MIN
+
+// a と b の最小値を求める
+#define	MIN(a, b)			((a) >= (b) ? (b) : (a))
+// a と b の最大値を求める
+#define	MAX(a, b)			((a) >= (b) ? (a) : (b))
+
+// int を bool にする
+#define	INT_TO_BOOL(i)		(((i) == 0) ? false : true)
+#define	MAKEBOOL(i)			INT_TO_BOOL(i)
+#define	BOOL_TO_INT(i)		(((i) == false) ? 0 : 1)
+
+// max_value よりも小さい a を返す
+#define	LESS(a, max_value)	((a) <= (max_value) ? (a) : (max_value))
+// min_value よりも大きい a を返す
+#define	MORE(a, min_value)	((a) >= (min_value) ? (a) : (min_value))
+// a が b と c の内部にある値かどうか調べる
+#define	INNER(a, b, c)		(((b) <= (c) && (a) >= (b) && (a) <= (c)) || ((b) >= (c) && (a) >= (c) && (a) <= (b)))
+// a が b と c の外部にある値かどうか調べる
+#define	OUTER(a, b, c)		(!INNER((a), (b), (c)))
+// a を b と c の間にある値となるように調整する
+#define	MAKESURE(a, b, c)		(((b) <= (c)) ? (MORE(LESS((a), (c)), (b))) : (MORE(LESS((a), (b)), (c))))
+
+// ポインタを UINT にする
+#define	POINTER_TO_KEY(p)		((sizeof(void *) == sizeof(UINT)) ? (UINT)(p) : HashPtrToUINT(p))
+// UINT とポインタを比較する
+#define	COMPARE_POINTER_AND_KEY(p, i)	(POINTER_TO_KEY(p) == (i))
+// ポインタを UINT64 にする
+#define	POINTER_TO_UINT64(p)	(((sizeof(void *) == sizeof(UINT64)) ? (UINT64)(p) : (UINT64)((UINT)(p))))
+// UINT64 をポインタにする
+#define	UINT64_TO_POINTER(i)	((sizeof(void *) == sizeof(UINT64)) ? (void *)(i) : (void *)((UINT)(i)))
+
+// 
+// 型宣言
+// 
+
+// BOOL 型
+#ifndef	WINDOWS_H
+typedef	unsigned int		BOOL;
+#define	TRUE				1
+#define	FALSE				0
+#endif	// WINDOWS_H
+
+// bool 型
+#ifndef	WIN32HTML_CPP
+typedef	unsigned int		bool;
+#define	true				1
+#define	false				0
+#endif	// WIN32HTML_CPP
+
+// 32bit 整数型
+#ifndef	WINDOWS_H
+typedef	unsigned int		UINT;
+typedef	unsigned int		UINT32;
+typedef	unsigned int		DWORD;
+typedef	signed int			INT;
+typedef	signed int			INT32;
+
+typedef	int					UINT_PTR;
+typedef	long				LONG_PTR;
+
+#endif
+
+// 16bit 整数型
+typedef	unsigned short		WORD;
+typedef	unsigned short		USHORT;
+typedef	signed short		SHORT;
+
+// 8bit 整数型
+typedef	unsigned char		BYTE;
+typedef	unsigned char		UCHAR;
+
+#ifndef	WIN32HTML_CPP
+typedef signed char			CHAR;
+#endif	// WIN32HTML_CPP
+
+
+// 64bit 整数型
+typedef	unsigned long long	UINT64;
+typedef signed long long	INT64;
+
+#ifdef	OS_UNIX
+// コンパイルエラーの回避
+#define	__cdecl
+#define	__declspec(x)
+// socket 型
+typedef	int SOCKET;
+#else	// OS_UNIX
+#ifndef	_WINSOCK2API_
+typedef UINT_PTR SOCKET;
+#endif	// _WINSOCK2API_
+#endif	// OS_UNIX
+
+// OS の種類
+#define	OSTYPE_WINDOWS_95						1100	// Windows 95
+#define	OSTYPE_WINDOWS_98						1200	// Windows 98
+#define	OSTYPE_WINDOWS_ME						1300	// Windows Me
+#define	OSTYPE_WINDOWS_UNKNOWN					1400	// Windows (不明)
+#define	OSTYPE_WINDOWS_NT_4_WORKSTATION			2100	// Windows NT 4.0 Workstation
+#define	OSTYPE_WINDOWS_NT_4_SERVER				2110	// Windows NT 4.0 Server
+#define	OSTYPE_WINDOWS_NT_4_SERVER_ENTERPRISE	2111	// Windows NT 4.0 Server, Enterprise Edition
+#define	OSTYPE_WINDOWS_NT_4_TERMINAL_SERVER		2112	// Windows NT 4.0 Terminal Server
+#define	OSTYPE_WINDOWS_NT_4_BACKOFFICE			2113	// BackOffice Server 4.5
+#define	OSTYPE_WINDOWS_NT_4_SMS					2114	// Small Business Server 4.5
+#define	OSTYPE_WINDOWS_2000_PROFESSIONAL		2200	// Windows 2000 Professional
+#define	OSTYPE_WINDOWS_2000_SERVER				2211	// Windows 2000 Server
+#define	OSTYPE_WINDOWS_2000_ADVANCED_SERVER		2212	// Windows 2000 Advanced Server
+#define	OSTYPE_WINDOWS_2000_DATACENTER_SERVER	2213	// Windows 2000 Datacenter Server
+#define	OSTYPE_WINDOWS_2000_BACKOFFICE			2214	// BackOffice Server 2000
+#define	OSTYPE_WINDOWS_2000_SBS					2215	// Small Business Server 2000
+#define	OSTYPE_WINDOWS_XP_HOME					2300	// Windows XP Home Edition
+#define	OSTYPE_WINDOWS_XP_PROFESSIONAL			2301	// Windows XP Professional
+#define	OSTYPE_WINDOWS_2003_WEB					2410	// Windows Server 2003 Web Edition
+#define	OSTYPE_WINDOWS_2003_STANDARD			2411	// Windows Server 2003 Standard Edition
+#define	OSTYPE_WINDOWS_2003_ENTERPRISE			2412	// Windows Server 2003 Enterprise Edition
+#define	OSTYPE_WINDOWS_2003_DATACENTER			2413	// Windows Server 2003 DataCenter Edition
+#define	OSTYPE_WINDOWS_2003_BACKOFFICE			2414	// BackOffice Server 2003
+#define	OSTYPE_WINDOWS_2003_SBS					2415	// Small Business Server 2003
+#define	OSTYPE_WINDOWS_LONGHORN_PROFESSIONAL	2500	// Windows Vista
+#define	OSTYPE_WINDOWS_LONGHORN_SERVER			2510	// Windows Server 2008
+#define	OSTYPE_WINDOWS_7						2600	// Windows 7
+#define	OSTYPE_WINDOWS_SERVER_2008_R2			2610	// Windows Server 2008 R2
+#define	OSTYPE_WINDOWS_8						2700	// Windows 8
+#define	OSTYPE_WINDOWS_SERVER_8					2710	// Windows Server 8
+#define	OSTYPE_UNIX_UNKNOWN						3000	// 不明な UNIX
+#define	OSTYPE_LINUX							3100	// Linux
+#define	OSTYPE_SOLARIS							3200	// Solaris
+#define	OSTYPE_CYGWIN							3300	// Cygwin
+#define	OSTYPE_BSD								3400	// BSD
+#define	OSTYPE_MACOS_X							3500	// MacOS X
+
+
+// OS 判別用マクロ
+#define	GET_KETA(t, i)			(((t) % (i * 10)) / i)
+#define	OS_IS_WINDOWS_9X(t)		(GET_KETA(t, 1000) == 1)
+#define	OS_IS_WINDOWS_NT(t)		(GET_KETA(t, 1000) == 2)
+#define	OS_IS_WINDOWS(t)		(OS_IS_WINDOWS_9X(t) || OS_IS_WINDOWS_NT(t))
+#define	OS_IS_SERVER(t)			(OS_IS_WINDOWS_NT(t) && GET_KETA(t, 10))
+#define	OS_IS_WORKSTATION(t)	((OS_IS_WINDOWS_NT(t) && (!(GET_KETA(t, 10)))) || OS_IS_WINDOWS_9X(t))
+#define	OS_IS_UNIX(t)			(GET_KETA(t, 1000) == 3)
+
+
+// OS 情報
+typedef struct OS_INFO
+{
+	UINT OsType;								// OS の種類
+	UINT OsServicePack;							// サービスパック番号
+	char *OsSystemName;							// OS システム名
+	char *OsProductName;						// OS 製品名
+	char *OsVendorName;							// OS ベンダ名
+	char *OsVersion;							// OS バージョン
+	char *KernelName;							// カーネル名
+	char *KernelVersion;						// カーネルバージョン
+} OS_INFO;
+
+// 時刻型
+#ifndef	WINDOWS_H
+typedef struct SYSTEMTIME
+{
+	WORD wYear;
+	WORD wMonth;
+	WORD wDayOfWeek;
+	WORD wDay;
+	WORD wHour;
+	WORD wMinute;
+	WORD wSecond;
+	WORD wMilliseconds;
+} SYSTEMTIME;
+#endif	// WINDOWS_H
+
+
+// Object.h
+typedef struct LOCK LOCK;
+typedef struct COUNTER COUNTER;
+typedef struct REF REF;
+typedef struct EVENT EVENT;
+typedef struct DEADCHECK DEADCHECK;
+
+// Tracking.h
+typedef struct CALLSTACK_DATA CALLSTACK_DATA;
+typedef struct TRACKING_OBJECT TRACKING_OBJECT;
+typedef struct MEMORY_STATUS MEMORY_STATUS;
+typedef struct TRACKING_LIST TRACKING_LIST;
+
+// FileIO.h
+typedef struct IO IO;
+
+// Memory.h
+typedef struct MEMTAG MEMTAG;
+typedef struct BUF BUF;
+typedef struct FIFO FIFO;
+typedef struct LIST LIST;
+typedef struct QUEUE QUEUE;
+typedef struct SK SK;
+typedef struct CANDIDATE CANDIDATE;
+typedef struct STRMAP_ENTRY STRMAP_ENTRY;
+
+// Str.h
+typedef struct TOKEN_LIST TOKEN_LIST;
+typedef struct INI_ENTRY INI_ENTRY;
+
+// Internat.h
+typedef struct UNI_TOKEN_LIST UNI_TOKEN_LIST;
+
+// Encrypt.h
+typedef struct CRYPT CRYPT;
+typedef struct NAME NAME;
+typedef struct X_SERIAL X_SERIAL;
+typedef struct X X;
+typedef struct K K;
+typedef struct P12 P12;
+typedef struct X_CRL X_CRL;
+
+// Secure.h
+typedef struct SECURE_DEVICE SECURE_DEVICE;
+typedef struct SEC_INFO SEC_INFO;
+typedef struct SECURE SECURE;
+typedef struct SEC_OBJ SEC_OBJ;
+
+// Kernel.h
+typedef struct MEMINFO MEMINFO;
+typedef struct LOCALE LOCALE;
+typedef struct THREAD THREAD;
+typedef struct THREAD_POOL_DATA THREAD_POOL_DATA;
+typedef struct INSTANCE INSTANCE;
+
+// Pack.h
+typedef struct VALUE VALUE;
+typedef struct ELEMENT ELEMENT;
+typedef struct PACK PACK;
+
+// Cfg.h
+typedef struct FOLDER FOLDER;
+typedef struct ITEM ITEM;
+typedef struct CFG_RW CFG_RW;
+typedef struct CFG_ENUM_PARAM CFG_ENUM_PARAM;
+
+// Table.h
+typedef struct TABLE TABLE;
+
+// Network.h
+typedef struct IP IP;
+typedef struct DNSCACHE DNSCACHE;
+typedef struct SOCK_EVENT SOCK_EVENT;
+typedef struct SOCK SOCK;
+typedef struct SOCKSET SOCKSET;
+typedef struct CANCEL CANCEL;
+typedef struct ROUTE_ENTRY ROUTE_ENTRY;
+typedef struct ROUTE_TABLE ROUTE_TABLE;
+//typedef struct SOCKLIST SOCKLIST;
+typedef struct IP_CLIENT IP_CLIENT;
+typedef struct ROUTE_CHANGE ROUTE_CHANGE;
+typedef struct ROUTE_CHANGE_DATA ROUTE_CHANGE_DATA;
+typedef struct GETIP_THREAD_PARAM GETIP_THREAD_PARAM;
+typedef struct WIN32_RELEASEADDRESS_THREAD_PARAM WIN32_RELEASEADDRESS_THREAD_PARAM;
+typedef struct IPV6_ADDR IPV6_ADDR;
+
+// Tick64.h
+typedef struct ADJUST_TIME ADJUST_TIME;
+typedef struct TICK64 TICK64;
+
+// FileIO.h
+typedef struct DIRENT DIRENT;
+typedef struct DIRLIST DIRLIST;
+
+
+
+
+#endif	// MAYATYPE_H
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Mayaqua.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Mayaqua.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Mayaqua.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,1174 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Mayaqua.c
+// Mayaqua Kernel プログラム
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <locale.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+// グローバル変数
+bool g_memcheck;								// メモリチェックの有効化
+bool g_debug;									// デバッグモード
+UINT64 kernel_status[NUM_KERNEL_STATUS];		// カーネル状態
+UINT64 kernel_status_max[NUM_KERNEL_STATUS];	// カーネル状態 (最大値)
+LOCK *kernel_status_lock[NUM_KERNEL_STATUS];	// カーネル状態ロック
+BOOL kernel_status_inited = false;				// カーネル状態初期化フラグ
+bool g_little_endian = true;
+char *cmdline = NULL;							// コマンドライン
+wchar_t *uni_cmdline = NULL;					// Unicode コマンドライン
+
+// スタティック変数
+static char *exename = NULL;						// EXE ファイル名 (ANSI)
+static wchar_t *exename_w = NULL;					// EXE ファイル名 (Unicode)
+static TOKEN_LIST *cmdline_token = NULL;			// コマンドライントークン
+static UNI_TOKEN_LIST *cmdline_uni_token = NULL;	// コマンドライントークン (Unicode)
+static OS_INFO *os_info = NULL;						// OS 情報
+static bool dot_net_mode = false;
+static bool minimal_mode = false;
+static UINT last_time_check = 0;
+static UINT first_time_check = 0;
+static bool is_nt = false;
+static bool is_ham_mode = false;
+static UINT init_mayaqua_counter = 0;
+static bool use_probe = false;
+static BUF *probe_buf = NULL;
+static LOCK *probe_lock = NULL;
+static UINT64 probe_start = 0;
+static UINT64 probe_last = 0;
+static bool probe_enabled = false;
+
+// チェックサムを計算する
+USHORT CalcChecksum16(void *buf, UINT size)
+{
+	int sum = 0;
+	USHORT *addr = (USHORT *)buf;
+	int len = (int)size;
+	USHORT *w = addr;
+	int nleft = len;
+	USHORT answer = 0;
+
+	while (nleft > 1)
+	{
+		sum += *w++;
+		nleft -= 2;
+	}
+
+	if (nleft == 1)
+	{
+		*(UCHAR *)(&answer) = *(UCHAR *)w;
+		sum += answer;
+	}
+
+	sum = (sum >> 16) + (sum & 0xffff);
+	sum += (sum >> 16);
+
+	answer = ~sum;
+
+	return answer;
+}
+
+// データ付き Probe の書き込み
+void WriteProbeData(char *filename, UINT line, char *str, void *data, UINT size)
+{
+	char tmp[MAX_SIZE];
+	USHORT cs;
+
+	if (IsProbeEnabled() == false)
+	{
+		return;
+	}
+
+	// データのチェックサムをとる
+	if (size != 0)
+	{
+		cs = CalcChecksum16(data, size);
+	}
+	else
+	{
+		cs = 0;
+	}
+
+	// 文字列の生成
+	snprintf(tmp, sizeof(tmp), "\"%s\" (Size=%5u, Crc=0x%04X)", str, size, cs);
+
+	WriteProbe(filename, line, tmp);
+}
+
+// Probe の書き込み
+void WriteProbe(char *filename, UINT line, char *str)
+{
+#ifdef	OS_WIN32
+	char *s;
+	char tmp[MAX_SIZE];
+	char tmp2[MAX_SIZE];
+	UINT64 now = 0;
+	UINT64 time;
+
+	if (IsProbeEnabled() == false)
+	{
+		return;
+	}
+
+	now = MsGetHiResCounter();
+
+	Lock(probe_lock);
+	{
+		UINT64 diff;
+		
+		time = MsGetHiResTimeSpanUSec(now - probe_start);
+
+		diff = time - probe_last;
+
+		if (time < probe_last)
+		{
+			diff = 0;
+		}
+
+		probe_last = time;
+
+		ToStr64(tmp, time);
+		MakeCharArray2(tmp2, ' ', (UINT)(MIN(12, (int)12 - (int)StrLen(tmp))));
+		WriteBuf(probe_buf, tmp2, StrLen(tmp2));
+		WriteBuf(probe_buf, tmp, StrLen(tmp));
+
+		s = " [+";
+		WriteBuf(probe_buf, s, StrLen(s));
+
+		ToStr64(tmp, diff);
+		MakeCharArray2(tmp2, ' ', (UINT)(MIN(12, (int)12 - (int)StrLen(tmp))));
+		WriteBuf(probe_buf, tmp2, StrLen(tmp2));
+		WriteBuf(probe_buf, tmp, StrLen(tmp));
+
+		s = "] - ";
+		WriteBuf(probe_buf, s, StrLen(s));
+
+		WriteBuf(probe_buf, filename, StrLen(filename));
+
+		s = "(";
+		WriteBuf(probe_buf, s, StrLen(s));
+
+		ToStr64(tmp, (UINT64)line);
+		WriteBuf(probe_buf, tmp, StrLen(tmp));
+
+		s = "): ";
+		WriteBuf(probe_buf, s, StrLen(s));
+
+		WriteBuf(probe_buf, str, StrLen(str));
+
+		s = "\r\n";
+		WriteBuf(probe_buf, s, StrLen(s));
+	}
+	Unlock(probe_lock);
+#endif	// OS_WIN32
+}
+
+// Probe の初期化
+void InitProbe()
+{
+	probe_buf = NewBuf();
+	probe_lock = NewLock();
+	probe_enabled = false;
+
+	probe_start = 0;
+
+#ifdef	OS_WIN32
+	probe_start = MsGetHiResCounter();
+#endif	// OS_WIN32
+}
+
+// Probe の解放
+void FreeProbe()
+{
+	if (probe_buf->Size >= 1)
+	{
+		SYSTEMTIME st;
+		char filename[MAX_SIZE];
+
+		// ファイルにすべて書き出す
+		MakeDirEx("@probe_log");
+
+		LocalTime(&st);
+
+		snprintf(filename, sizeof(filename), "@probe_log/%04u%02u%02u_%02u%02u%02u.log",
+			st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
+
+		DumpBuf(probe_buf, filename);
+	}
+
+	FreeBuf(probe_buf);
+	DeleteLock(probe_lock);
+}
+
+// Probe を有効 / 無効にする
+void EnableProbe(bool enable)
+{
+	probe_enabled = enable;
+}
+
+// Probe が有効かどうか取得する
+bool IsProbeEnabled()
+{
+#ifndef	USE_PROBE
+	return false;
+#else	// USE_PROBE
+	return probe_enabled;
+#endif	// USE_PROBE
+}
+
+// Ham モードに設定する
+void SetHamMode()
+{
+	is_ham_mode = true;
+}
+
+// Ham モードかどうか取得する
+bool IsHamMode()
+{
+	return is_ham_mode;
+}
+
+// 前回の呼び出しから現在までにかかった時間を表示
+void TimeCheck()
+{
+#ifdef OS_WIN32
+	UINT now, ret, total;
+	now = Win32GetTick();
+	if (last_time_check == 0)
+	{
+		ret = 0;
+	}
+	else
+	{
+		ret = now - last_time_check;
+	}
+	last_time_check = now;
+
+	if (first_time_check == 0)
+	{
+		first_time_check = now;
+	}
+
+	total = now - first_time_check;
+
+	printf(" -- %3.3f / %3.3f\n", (double)ret / 1000.0f, (double)total / 1000.0f);
+#endif	// OS_WIN32
+}
+
+// IA64 かどうか
+bool IsIA64()
+{
+	if (Is64() == false)
+	{
+		return false;
+	}
+
+#ifndef	MAYAQUA_IA_64
+	return false;
+#else	// MAYAQUA_IA_64
+	return true;
+#endif	// MAYAQUA_IA_64
+}
+
+// x64 かどうか
+bool IsX64()
+{
+	if (Is64() == false)
+	{
+		return false;
+	}
+
+#ifndef	MAYAQUA_IA_64
+	return true;
+#else	// MAYAQUA_IA_64
+	return false;
+#endif	// MAYAQUA_IA_64
+}
+
+// 64bit かどうか
+bool Is64()
+{
+#ifdef	CPU_64
+	return true;
+#else	// CPU_64
+	return false;
+#endif	// CPU_64
+}
+
+// 32bit かどうか
+bool Is32()
+{
+	return Is64() ? false : true;
+}
+
+// .NET モード
+void MayaquaDotNetMode()
+{
+	dot_net_mode = true;
+}
+
+// .NET モードかどうか取得
+bool MayaquaIsDotNetMode()
+{
+	return dot_net_mode;
+}
+
+// エンディアンチェック
+void CheckEndian()
+{
+	unsigned short test;
+	UCHAR *buf;
+
+	test = 0x1234;
+	buf = (UCHAR *)&test;
+	if (buf[0] == 0x12)
+	{
+		g_little_endian = false;
+	}
+	else
+	{
+		g_little_endian = true;
+	}
+}
+
+// 最小モードにする
+void MayaquaMinimalMode()
+{
+	minimal_mode = true;
+}
+bool MayaquaIsMinimalMode()
+{
+	return minimal_mode;
+}
+
+// NT かどうか
+bool IsNt()
+{
+	return is_nt;
+}
+
+// Unicode をサポートしているかどうか
+bool IsUnicode()
+{
+#ifdef	OS_WIN32
+	// Windows
+	return IsNt();
+#else	// OS_WIN32
+	// UNIX
+	return true;
+#endif	// OS_WIN32
+}
+
+// Mayaqua ライブラリの初期化
+void InitMayaqua(bool memcheck, bool debug, int argc, char **argv)
+{
+	wchar_t tmp[MAX_PATH];
+
+	if ((init_mayaqua_counter++) > 0)
+	{
+		return;
+	}
+
+	g_memcheck = memcheck;
+	g_debug = debug;
+	cmdline = NULL;
+	if (dot_net_mode == false)
+	{
+		// .NET モードでこれを呼ぶとなぜか落ちる
+		setbuf(stdout, NULL);
+	}
+
+	// NT かどうか取得
+#ifdef	OS_WIN32
+	is_nt = Win32IsNt();
+#endif	// OS_WIN32
+
+	// エンディアンチェック
+	CheckEndian();
+
+#ifdef	OS_WIN32
+	_configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
+#endif	// OS_WIN32
+
+	// CRT のロケール情報を日本語にする
+	setlocale(LC_ALL, "");
+
+	// OS の初期化
+	OSInit();
+
+	// 乱数の初期化
+	srand((UINT)SystemTime64());
+
+	tick_manual_lock = NewLock();
+
+	// FIFO システムの初期化
+	InitFifo();
+
+	// カーネルステータスの初期化
+	InitKernelStatus();
+
+	// トラッキングの初期化
+	InitTracking();
+
+	// スレッドプールの初期化
+	InitThreading();
+
+	// 文字列ライブラリの初期化
+	InitStringLibrary();
+
+	// ロケール情報の初期化
+	SetLocale(NULL);
+
+	// 暗号化ライブラリの初期化
+	InitCryptLibrary();
+
+	// リアルタイムクロックの初期化
+	InitTick64();
+
+	// ネットワーク通信モジュールの初期化
+	InitNetwork();
+
+	// EXE ファイル名の取得の初期化
+	InitGetExeName(argc >= 1 ? argv[0] : NULL);
+
+	// コマンドライン文字列の初期化
+	InitCommandLineStr(argc, argv);
+
+	// OS 情報の初期化
+	InitOsInfo();
+
+	// オペレーティングシステム固有の初期化
+#ifdef	OS_WIN32
+	MsInit();	// Microsoft Win32
+#endif	// OS_WIN32
+
+	// セキュリティトークンモジュールの初期化
+	InitSecure();
+
+	if (OSIsSupportedOs() == false)
+	{
+		// 強制終了
+		exit(0);
+	}
+
+	// RSA チェック
+	if (RsaCheckEx() == false)
+	{
+		// 強制終了
+		Alert("OpenSSL Library Init Failed. (too old?)\nPlease install the latest version of OpenSSL.\n\n", "RsaCheck()");
+		exit(0);
+	}
+
+	// HamCore ファイルシステムの初期化
+	InitHamcore();
+
+	// デフォルトで japanese.stb を読み込む
+	LoadTable(DEFAULT_TABLE_FILE_NAME);
+
+	if (exename == NULL)
+	{
+		// 実行可能ファイル名
+		exename = CopyStr("unknown");
+	}
+
+	// 自分自身の実行可能ファイル名が見つかるかどうか検査する
+	// (見つからない場合は変なパスで起動されているので終了する)
+	GetExeNameW(tmp, sizeof(tmp));
+	if (IsFileExistsW(tmp) == false)
+	{
+		wchar_t tmp2[MAX_SIZE];
+
+		UniFormat(tmp2, sizeof(tmp2),
+			L"Error: Executable binary file \"%s\" not found.\r\n\r\n"
+			L"Please execute program with full path.\r\n",
+			tmp);
+
+		AlertW(tmp2, NULL);
+		_exit(0);
+	}
+
+	CheckUnixTempDir();
+
+	// Probe の初期化
+	InitProbe();
+}
+
+// Mayaqua ライブラリの解放
+void FreeMayaqua()
+{
+	if ((--init_mayaqua_counter) > 0)
+	{
+		return;
+	}
+
+	// Probe の解放
+	FreeProbe();
+
+	// テーブルを削除
+	FreeTable();
+
+	// セキュリティトークンモジュールの解放
+	FreeSecure();
+
+	// オペレーティングシステム固有の解放
+#ifdef	OS_WIN32
+	MsFree();
+#endif	// OS_WIN32
+
+	// OS 情報の解放
+	FreeOsInfo();
+
+	// HamCore ファイルシステムの解放
+	FreeHamcore();
+
+	// コマンドライン文字列の解放
+	FreeCommandLineStr();
+
+	// コマンドライントークンの解放
+	FreeCommandLineTokens();
+
+	// ネットワーク通信モジュールの解放
+	FreeNetwork();
+
+	// リアルタイムクロックの解放
+	FreeTick64();
+
+	// 暗号化ライブラリの解放
+	FreeCryptLibrary();
+
+	// 文字列ライブラリの解放
+	FreeStringLibrary();
+
+	// スレッドプールの解放
+	FreeThreading();
+
+#ifndef	VPN_SPEED
+	// カーネル状態の表示
+	if (g_debug)
+	{
+		PrintKernelStatus();
+	}
+
+	// デバッグ情報の表示
+	if (g_memcheck)
+	{
+		PrintDebugInformation();
+	}
+#endif	// VPN_SPEED
+
+	// トラッキングの解放
+	FreeTracking();
+
+	// カーネルステータスの解放
+	FreeKernelStatus();
+
+	DeleteLock(tick_manual_lock);
+	tick_manual_lock = NULL;
+
+	// OS の解放
+	OSFree();
+}
+
+// UNIX で /tmp が使用できるかどうか確認する
+void CheckUnixTempDir()
+{
+	if (OS_IS_UNIX(GetOsInfo()->OsType))
+	{
+		char tmp[128], tmp2[64];
+		UINT64 now = SystemTime64();
+		IO *o;
+
+		MakeDir("/tmp");
+
+		Format(tmp2, sizeof(tmp2), "%I64u", now);
+
+		Format(tmp, sizeof(tmp), "/tmp/.%s", tmp2);
+
+		o = FileCreate(tmp);
+		if (o == NULL)
+		{
+			o = FileOpen(tmp, false);
+			if (o == NULL)
+			{
+				Print("Unable to use /tmp.\n\n");
+				exit(0);
+				return;
+			}
+		}
+
+		FileClose(o);
+
+		FileDelete(tmp);
+	}
+}
+
+// アラートの表示
+void Alert(char *msg, char *caption)
+{
+	OSAlert(msg, caption);
+}
+void AlertW(wchar_t *msg, wchar_t *caption)
+{
+	OSAlertW(msg, caption);
+}
+
+// OS 情報の表示
+void PrintOsInfo(OS_INFO *info)
+{
+	// 引数チェック
+	if (info == NULL)
+	{
+		return;
+	}
+
+	Print(
+		"OS Type          : %u\n"
+		"OS Service Pack  : %u\n"
+		"os_is_windows    : %s\n"
+		"os_is_windows_nt : %s\n"
+		"OS System Name   : %s\n"
+		"OS Product Name  : %s\n"
+		"OS Vendor Name   : %s\n"
+		"OS Version       : %s\n"
+		"Kernel Name      : %s\n"
+		"Kernel Version   : %s\n",
+		info->OsType,
+		info->OsServicePack,
+		OS_IS_WINDOWS(info->OsType) ? "true" : "false",
+		OS_IS_WINDOWS_NT(info->OsType) ? "true" : "false",
+		info->OsSystemName,
+		info->OsProductName,
+		info->OsVendorName,
+		info->OsVersion,
+		info->KernelName,
+		info->KernelVersion);
+
+#ifdef	OS_WIN32
+	{
+		char *exe, *dir;
+		exe = MsGetExeFileName();
+		dir = MsGetExeDirName();
+
+		Print(
+			"EXE File Path    : %s\n"
+			"EXE Dir Path     : %s\n"
+			"Process Id       : %u\n"
+			"Process Handle   : 0x%X\n",
+			exe, dir, MsGetCurrentProcessId(), MsGetCurrentProcess());
+	}
+#endif	// OS_WIN32
+}
+
+// OS 種類の取得
+UINT GetOsType()
+{
+	OS_INFO *i = GetOsInfo();
+
+	if (i == NULL)
+	{
+		return 0;
+	}
+
+	return i->OsType;
+}
+
+// OS 情報の取得
+OS_INFO *GetOsInfo()
+{
+	return os_info;
+}
+
+// OS 情報の初期化
+void InitOsInfo()
+{
+	if (os_info != NULL)
+	{
+		return;
+	}
+
+	os_info = ZeroMalloc(sizeof(OS_INFO));
+
+	OSGetOsInfo(os_info);
+}
+
+// OS 情報の解放
+void FreeOsInfo()
+{
+	if (os_info == NULL)
+	{
+		return;
+	}
+
+	Free(os_info->OsSystemName);
+	Free(os_info->OsProductName);
+	Free(os_info->OsVendorName);
+	Free(os_info->OsVersion);
+	Free(os_info->KernelName);
+	Free(os_info->KernelVersion);
+	Free(os_info);
+
+	os_info = NULL;
+}
+
+// Unicode コマンドライントークンの取得
+UNI_TOKEN_LIST *GetCommandLineUniToken()
+{
+	if (cmdline_uni_token == NULL)
+	{
+		return UniNullToken();
+	}
+	else
+	{
+		return UniCopyToken(cmdline_uni_token);
+	}
+}
+
+// コマンドライントークンの取得
+TOKEN_LIST *GetCommandLineToken()
+{
+	if (cmdline_token == NULL)
+	{
+		return NullToken();
+	}
+	else
+	{
+		return CopyToken(cmdline_token);
+	}
+}
+
+// コマンドライン文字列をトークンに変換する
+void ParseCommandLineTokens()
+{
+	if (cmdline_token != NULL)
+	{
+		FreeToken(cmdline_token);
+	}
+	cmdline_token = ParseCmdLine(cmdline);
+
+	if (cmdline_uni_token != NULL)
+	{
+		UniFreeToken(cmdline_uni_token);
+	}
+	cmdline_uni_token = UniParseCmdLine(uni_cmdline);
+}
+
+// コマンドライントークンを解放する
+void FreeCommandLineTokens()
+{
+	if (cmdline_token != NULL)
+	{
+		FreeToken(cmdline_token);
+	}
+	cmdline_token = NULL;
+
+	if (cmdline_uni_token != NULL)
+	{
+		UniFreeToken(cmdline_uni_token);
+	}
+	cmdline_uni_token = NULL;
+}
+
+// コマンドライン文字列の初期化
+void InitCommandLineStr(int argc, char **argv)
+{
+	if (argc >= 1)
+	{
+#ifdef	OS_UNIX
+		exename_w = CopyUtfToUni(argv[0]);
+		exename = CopyUniToStr(exename_w);
+#else	// OS_UNIX
+		exename = CopyStr(argv[0]);
+		exename_w = CopyStrToUni(exename);
+#endif	// OS_UNIX
+	}
+	if (argc < 2 || argv == NULL)
+	{
+		// コマンドライン文字列無し
+		SetCommandLineStr(NULL);
+	}
+	else
+	{
+		// コマンドライン文字列有り
+		int i, total_len = 1;
+		char *tmp;
+
+		for (i = 1;i < argc;i++)
+		{
+			total_len += StrLen(argv[i]) * 2 + 32;
+		}
+		tmp = ZeroMalloc(total_len);
+
+		for (i = 1;i < argc;i++)
+		{
+			UINT s_size = StrLen(argv[i]) * 2;
+			char *s = ZeroMalloc(s_size);
+			bool dq = (SearchStrEx(argv[i], " ", 0, true) != INFINITE);
+			ReplaceStrEx(s, s_size, argv[i], "\"", "\"\"", true);
+			if (dq)
+			{
+				StrCat(tmp, total_len, "\"");
+			}
+			StrCat(tmp, total_len, s);
+			if (dq)
+			{
+				StrCat(tmp, total_len, "\"");
+			}
+			StrCat(tmp, total_len, " ");
+			Free(s);
+		}
+
+		Trim(tmp);
+		SetCommandLineStr(tmp);
+		Free(tmp);
+	}
+}
+
+// コマンドライン文字列の解放
+void FreeCommandLineStr()
+{
+	SetCommandLineStr(NULL);
+
+	if (exename != NULL)
+	{
+		Free(exename);
+		exename = NULL;
+	}
+
+	if (exename_w != NULL)
+	{
+		Free(exename_w);
+		exename_w = NULL;
+	}
+}
+
+// Unicode コマンドライン文字列の取得
+wchar_t *GetCommandLineUniStr()
+{
+	if (uni_cmdline == NULL)
+	{
+		return UniCopyStr(L"");
+	}
+	else
+	{
+		return UniCopyStr(uni_cmdline);
+	}
+}
+
+// コマンドライン文字列の取得
+char *GetCommandLineStr()
+{
+	if (cmdline == NULL)
+	{
+		return CopyStr("");
+	}
+	else
+	{
+		return CopyStr(cmdline);
+	}
+}
+
+// Unicode コマンドライン文字列の設定
+void SetCommandLineUniStr(wchar_t *str)
+{
+	if (uni_cmdline != NULL)
+	{
+		Free(uni_cmdline);
+	}
+	if (str == NULL)
+	{
+		uni_cmdline = NULL;
+	}
+	else
+	{
+		uni_cmdline = CopyUniStr(str);
+	}
+
+	ParseCommandLineTokens();
+}
+
+// コマンドライン文字列の設定
+void SetCommandLineStr(char *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		if (cmdline != NULL)
+		{
+			Free(cmdline);
+		}
+		cmdline = NULL;
+	}
+	else
+	{
+		if (cmdline != NULL)
+		{
+			Free(cmdline);
+		}
+		cmdline = CopyStr(str);
+	}
+
+	if (cmdline == NULL)
+	{
+		if (uni_cmdline != NULL)
+		{
+			Free(uni_cmdline);
+			uni_cmdline = NULL;
+		}
+	}
+	else
+	{
+		if (uni_cmdline != NULL)
+		{
+			Free(uni_cmdline);
+		}
+		uni_cmdline = CopyStrToUni(cmdline);
+	}
+
+	ParseCommandLineTokens();
+}
+
+// カーネルステータスの表示
+void PrintKernelStatus()
+{
+	bool leaked = false;
+
+	Print("\n");
+	Print(
+		"     --------- Mayaqua Kernel Status ---------\n"
+		"        Malloc Count ............... %u\n"
+		"        ReAlloc Count .............. %u\n"
+		"        Free Count ................. %u\n"
+		"        Total Memory Size .......... %I64u bytes\n"
+		"      * Current Memory Blocks ...... %u Blocks (Peek: %u)\n"
+		"        Total Memory Blocks ........ %u Blocks\n"
+		"      * Current MemPool Blocks ..... %u Blocks (Peek: %u)\n"
+		"        Total MemPool Mallocs ...... %u Mallocs\n"
+		"        Total MemPool ReAllocs ..... %u ReAllocs\n"
+		"        NewLock Count .............. %u\n"
+		"        DeleteLock Count ........... %u\n"
+		"      * Current Lock Objects ....... %u Objects\n"
+		"      * Current Locked Objects ..... %u Objects\n"
+		"        NewRef Count ............... %u\n"
+		"        FreeRef Count .............. %u\n"
+		"      * Current Ref Objects ........ %u Objects\n"
+		"      * Current Ref Count .......... %u Refs\n"
+		"        GetTime Count .............. %u\n"
+		"        GetTick Count .............. %u\n"
+		"        NewThread Count ............ %u\n"
+		"        FreeThread Count ........... %u\n"
+		"      * Current Threads ............ %u Threads\n"
+		"        Wait For Event Count ....... %u\n\n",
+		KS_GET(KS_MALLOC_COUNT),
+		KS_GET(KS_REALLOC_COUNT),
+		KS_GET(KS_FREE_COUNT),
+		KS_GET64(KS_TOTAL_MEM_SIZE),
+		KS_GET(KS_CURRENT_MEM_COUNT),
+		KS_GETMAX(KS_CURRENT_MEM_COUNT),
+		KS_GET(KS_TOTAL_MEM_COUNT),
+		KS_GET(KS_MEMPOOL_CURRENT_NUM),
+		KS_GETMAX(KS_MEMPOOL_CURRENT_NUM),
+		KS_GET(KS_MEMPOOL_MALLOC_COUNT),
+		KS_GET(KS_MEMPOOL_REALLOC_COUNT),
+		KS_GET(KS_NEWLOCK_COUNT),
+		KS_GET(KS_DELETELOCK_COUNT),
+		KS_GET(KS_CURRENT_LOCK_COUNT),
+		KS_GET(KS_CURRENT_LOCKED_COUNT),
+		KS_GET(KS_NEWREF_COUNT),
+		KS_GET(KS_FREEREF_COUNT),
+		KS_GET(KS_CURRENT_REF_COUNT),
+		KS_GET(KS_CURRENT_REFED_COUNT),
+		KS_GET(KS_GETTIME_COUNT),
+		KS_GET(KS_GETTICK_COUNT),
+		KS_GET(KS_NEWTHREAD_COUNT),
+		KS_GET(KS_FREETHREAD_COUNT),
+		KS_GET(KS_NEWTHREAD_COUNT) - KS_GET(KS_FREETHREAD_COUNT),
+		KS_GET(KS_WAIT_COUNT)
+		);
+
+	if (KS_GET(KS_CURRENT_MEM_COUNT) != 0 || KS_GET(KS_CURRENT_LOCK_COUNT) != 0 ||
+		KS_GET(KS_MEMPOOL_CURRENT_NUM) != 0 ||
+		KS_GET(KS_CURRENT_LOCKED_COUNT) != 0 || KS_GET(KS_CURRENT_REF_COUNT) != 0)
+	{
+		leaked = true;
+	}
+
+	if (leaked)
+	{
+		Print("      !!! MEMORY LEAKS DETECTED !!!\n\n");
+		if (g_memcheck == false)
+		{
+			GetLine(NULL, 0);
+		}
+	}
+	else
+	{
+		Print("        @@@ NO MEMORY LEAKS @@@\n\n");
+	}
+}
+
+// カーネルステータスの初期化
+void InitKernelStatus()
+{
+	UINT i;
+
+	// メモリ初期化
+	Zero(kernel_status, sizeof(kernel_status));
+	Zero(kernel_status_max, sizeof(kernel_status_max));
+
+	// ロック初期化
+	for (i = 0;i < NUM_KERNEL_STATUS;i++)
+	{
+		kernel_status_lock[i] = OSNewLock();
+	}
+
+	kernel_status_inited = true;
+}
+
+// カーネルステータスの解放
+void FreeKernelStatus()
+{
+	UINT i;
+
+	kernel_status_inited = false;
+
+	// ロック解放
+	for (i = 0;i < NUM_KERNEL_STATUS;i++)
+	{
+		OSDeleteLock(kernel_status_lock[i]);
+	}
+}
+
+// カーネルステータスのロック
+void LockKernelStatus(UINT id)
+{
+	// 引数チェック
+	if (id >= NUM_KERNEL_STATUS)
+	{
+		return;
+	}
+
+	OSLock(kernel_status_lock[id]);
+}
+
+// カーネルステータスのロック解除
+void UnlockKernelStatus(UINT id)
+{
+	// 引数チェック
+	if (id >= NUM_KERNEL_STATUS)
+	{
+		return;
+	}
+
+	OSUnlock(kernel_status_lock[id]);
+}
+
+// デバッグ情報の表示
+void PrintDebugInformation()
+{
+	MEMORY_STATUS memory_status;
+	GetMemoryStatus(&memory_status);
+
+	// ヘッダ
+	Print("====== SoftEther UT-VPN System Debug Information ======\n");
+
+	// メモリ情報
+	Print(" <Memory Status>\n"
+		"       Number of Allocated Memory Blocks: %u\n"
+		"   Total Size of Allocated Memory Blocks: %u bytes\n",
+		memory_status.MemoryBlocksNum, memory_status.MemorySize);
+
+	// フッタ
+	Print("====================================================\n");
+
+	if (KS_GET(KS_CURRENT_MEM_COUNT) != 0 || KS_GET(KS_CURRENT_LOCK_COUNT) != 0 ||
+		KS_GET(KS_CURRENT_LOCKED_COUNT) != 0 || KS_GET(KS_CURRENT_REF_COUNT) != 0)
+	{
+		// メモリリークしている可能性があるのでデバッグメニューを出す
+		MemoryDebugMenu();
+	}
+}
+
+
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Mayaqua.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Mayaqua.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Mayaqua.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,554 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Mayaqua.h
+// Mayaqua Kernel ヘッダファイル
+
+#ifndef	MAYAQUA_H
+#define	MAYAQUA_H
+
+// PenCore.dll 関係
+#define	PENCORE_DLL_NAME		"|PenCore.dll"
+
+//#define	USE_PROBE						// Probe を使う
+
+// リリースフラグ用マクロ
+#ifdef	VPN_SPEED
+
+#define	DONT_USE_KERNEL_STATUS			// カーネルステータスを更新しない
+#define	WIN32_USE_HEAP_API_FOR_MEMORY	// メモリ確保にヒープ API を使用する
+#define	WIN32_NO_DEBUG_HELP_DLL			// デバッグ用 DLL を呼び出さない
+#define	DONT_CHECK_HEAP					// ヒープの状態をチェックしない
+
+#endif	// VPN_SPEED
+
+#ifdef	VPN_EXE
+// 実行可能ファイルビルド用
+#ifdef	WIN32
+#include <windows.h>
+#include "../PenCore/resource.h"
+int main(int argc, char *argv[]);
+int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrev, char *CmdLine, int CmdShow)
+{
+	return main(0, NULL);
+}
+#endif	// WIN32
+#endif	// VPN_EXE
+
+// 定数
+#define	DEFAULT_TABLE_FILE_NAME		"|strtable.stb"		// デフォルト文字列テーブル
+#define	STRTABLE_ID					"UT_VPN_20100520"	// 文字列テーブル識別子
+
+// OS の判別
+#ifdef	WIN32
+#define	OS_WIN32		// Microsoft Windows
+#else
+#define	OS_UNIX			// UNIX
+#endif	// WIN32
+
+// ディレクトリ区切り
+#ifdef	OS_WIN32
+#define	PATH_BACKSLASH	// バックスラッシュ (\)
+#else	// WIN32
+#define	PATH_SLASH		// スラッシュ (/)
+#endif	// WIN32
+
+// 文字コード
+#ifdef	OS_WIN32
+#define	CODE_SHIFTJIS	// Shift_JIS コード
+#else	// WIN32
+#define	CODE_EUC		// euc-jp コード
+#endif	// WIN32
+
+// エンディアン
+#define	IsBigEndian()		(g_little_endian ? false : true)
+#define	IsLittleEndian()	(g_little_endian)
+
+#ifdef	OS_WIN32
+// snprintf 関数の置換
+#define	snprintf	_snprintf
+#endif	// OS_WIN32
+
+// コンパイラ依存
+#ifndef	OS_WIN32
+// gcc コンパイラ
+#define	GCC_PACKED		__attribute__ ((__packed__))
+#else	// OS_WIN32
+// VC++ コンパイラ
+#define	GCC_PACKED
+#endif	// OS_WIN32
+
+// 現在のファイルと行番号を表示するマクロ
+#define	WHERE			printf("%s: %u\n", __FILE__, __LINE__); SleepThread(10);
+#define	WHERE32			{	\
+	char tmp[128]; sprintf(tmp, "%s: %u", __FILE__, __LINE__); Win32DebugAlert(tmp);	\
+	}
+#define TIMECHECK		printf("%-12s:%5u", __FILE__, __LINE__);TimeCheck();
+
+// プローブ関係
+#ifdef	USE_PROBE
+#define	PROBE_WHERE						WriteProbe(__FILE__, __LINE__, "");
+#define	PROBE_STR(str)					WriteProbe(__FILE__, __LINE__, (str));
+#define	PROBE_DATA2(str, data, size)	WriteProbeData(__FILE__, __LINE__, (str), (data), (size));
+#define	PROBE_DATA(data, size)			WriteProbeData(__FILE__, __LINE__, "", (data), (size));
+#else	// USE_PROBE
+#define	PROBE_WHERE
+#define	PROBE_STR(str)
+#define	PROBE_DATA2(str, data, size)
+#define	PROBE_DATA(data, size)
+#endif	// USE_PROBE
+
+// 現在の時間を表示するマクロ
+#ifdef	WIN32
+#define	WHEN			{WHERE; MsPrintTick();}
+#else	// WIN32
+#define	WHEN
+#endif	// WIN32
+
+#ifdef	OS_UNIX
+// UNIX 系 OS にのみ必要なヘッダ
+#include <sys/types.h>
+#include <unistd.h>
+#include <termios.h>
+#include <dirent.h>
+#ifdef	UNIX_LINUX
+#include <sys/vfs.h>
+#elif	UNIX_BSD
+#include <sys/param.h>
+#include <sys/mount.h>
+#endif
+#ifdef	UNIX_SOLARIS
+#include <sys/statvfs.h>
+#define	USE_STATVFS
+#endif	// UNIX_SOLARIS
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#ifdef	UNIX_SOLARIS
+#include <sys/filio.h>
+#endif	// UNIX_SOLARIS
+#include <sys/poll.h>
+#include <sys/resource.h>
+#include <pthread.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+//#include <netinet/ip.h>
+#include <netdb.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+//#include <curses.h>
+
+#ifdef	UNIX_LINUX
+typedef void *iconv_t;
+iconv_t iconv_open (__const char *__tocode, __const char *__fromcode);
+size_t iconv (iconv_t __cd, char **__restrict __inbuf,
+                     size_t *__restrict __inbytesleft,
+                     char **__restrict __outbuf,
+                     size_t *__restrict __outbytesleft);
+int iconv_close (iconv_t __cd);
+#else	// UNIX_LINUX
+#include <iconv.h>
+#endif	// UNIX_LINUX
+
+
+#ifdef	UNIX_LINUX
+#include <netinet/if_ether.h>
+#include <net/ethernet.h>
+#include <netpacket/packet.h>
+#endif	// UNIX_LINUX
+
+#ifdef	UNIX_SOLARIS
+#include <sys/dlpi.h>
+#include <sys/stropts.h>
+#include <sys/stream.h>
+#endif	// UNIX_SOLARIS
+
+#ifndef	NO_VLAN
+
+#include <Mayaqua/TunTap.h>
+
+#endif	// NO_VLAN
+
+#define	closesocket(s)		close(s)
+
+#else	// Win32 のみ
+
+#include <conio.h>
+
+#endif	// OS_UNIX
+
+// IPv6 サポートフラグ
+#ifndef	WIN32
+#ifndef	AF_INET6
+#define	NO_IPV6
+#endif	// AF_INET6
+#endif	// WIN32
+
+// 基本型宣言
+#include <Mayaqua/MayaType.h>
+
+// オブジェクト管理
+#include <Mayaqua/Object.h>
+
+// オブジェクト追跡
+#include <Mayaqua/Tracking.h>
+
+// ファイル入出力
+#include <Mayaqua/FileIO.h>
+
+// メモリ管理
+#include <Mayaqua/Memory.h>
+
+// 文字列処理
+#include <Mayaqua/Str.h>
+
+// 国際化文字列処理
+#include <Mayaqua/Internat.h>
+
+// 暗号化処理
+#include <Mayaqua/Encrypt.h>
+
+// セキュアトークン
+#include <Mayaqua/Secure.h>
+
+// カーネル
+#include <Mayaqua/Kernel.h>
+
+// パッケージ
+#include <Mayaqua/Pack.h>
+
+// 設定ファイル
+#include <Mayaqua/Cfg.h>
+
+// 文字列テーブル
+#include <Mayaqua/Table.h>
+
+// ネットワーク通信
+#include <Mayaqua/Network.h>
+
+// 64 bit リアルタイムクロック
+#include <Mayaqua/Tick64.h>
+
+// OS 依存コード
+#include <Mayaqua/OS.h>
+
+// Microsoft Windows 用コード
+#include <Mayaqua/Microsoft.h>
+
+
+// グローバル変数
+extern bool g_memcheck;
+extern bool g_debug;
+extern char *cmdline;
+extern wchar_t *uni_cmdline;
+extern bool g_little_endian;
+extern LOCK *tick_manual_lock;
+
+// カーネル状態
+#define	NUM_KERNEL_STATUS	128
+extern UINT64 kernel_status[NUM_KERNEL_STATUS];
+extern UINT64 kernel_status_max[NUM_KERNEL_STATUS];
+extern LOCK *kernel_status_lock[NUM_KERNEL_STATUS];
+extern BOOL kernel_status_inited;
+
+// カーネル状態操作マクロ
+#define	KS_LOCK(id)		LockKernelStatus(id)
+#define	KS_UNLOCK(id)	UnlockKernelStatus(id)
+#define	KS_GET64(id)	(kernel_status[id])
+#define	KS_GET(id)		((UINT)KS_GET64(id))
+#define	KS_GETMAX64(id)	(kernel_status_max[id])
+#define	KS_GETMAX(id)	((UINT)KS_GETMAX64(id))
+
+#ifdef	DONT_USE_KERNEL_STATUS
+// カーネルステータス操作を無効にする
+#define	KS_INC(id)
+#define	KS_DEC(id)
+#define	KS_ADD(id, n)
+#define	KS_SUB(id, n)
+#else	// DONT_USE_KERNEL_STATUS
+// カーネルステータス操作を有効にする
+#define	KS_INC(id)							\
+if (kernel_status_inited) {					\
+	KS_LOCK(id);							\
+	kernel_status[id]++;					\
+	kernel_status_max[id] = MAX(kernel_status_max[id], kernel_status[id]);	\
+	KS_UNLOCK(id);							\
+}
+#define	KS_DEC(id)							\
+if (kernel_status_inited) {					\
+	KS_LOCK(id);							\
+	kernel_status[id]--;					\
+	kernel_status_max[id] = MAX(kernel_status_max[id], kernel_status[id]);	\
+	KS_UNLOCK(id);							\
+}
+#define	KS_ADD(id, n)						\
+if (kernel_status_inited) {					\
+	KS_LOCK(id);							\
+	kernel_status[id] += n;					\
+	kernel_status_max[id] = MAX(kernel_status_max[id], kernel_status[id]);	\
+	KS_UNLOCK(id);							\
+}
+#define	KS_SUB(id, n)						\
+if (kernel_status_inited) {					\
+	KS_LOCK(id);							\
+	kernel_status[id] -= n;					\
+	kernel_status_max[id] = MAX(kernel_status_max[id], kernel_status[id]);	\
+	KS_UNLOCK(id);							\
+}
+#endif	// DONT_USE_KERNEL_STATUS
+
+// カーネル状態一覧
+// 文字列関係
+#define	KS_STRCPY_COUNT			0		// StrCpy 呼び出し回数
+#define	KS_STRLEN_COUNT			1		// StrLen 呼び出し回数
+#define	KS_STRCHECK_COUNT		2		// StrCheck 呼び出し回数
+#define	KS_STRCAT_COUNT			3		// StrCat 呼び出し回数
+#define	KS_FORMAT_COUNT			4		// Format 呼び出し回数
+// メモリ関係
+#define	KS_MALLOC_COUNT			5		// Malloc 呼び出し回数
+#define	KS_REALLOC_COUNT		6		// ReAlloc 呼び出し回数
+#define	KS_FREE_COUNT			7		// Free 呼び出し回数
+#define	KS_TOTAL_MEM_SIZE		8		// これまでに確保したメモリの合計サイズ
+#define	KS_CURRENT_MEM_COUNT	9		// 現在確保しているメモリブロック数
+#define	KS_TOTAL_MEM_COUNT		10		// これまでに確保したメモリブロック数の合計
+#define	KS_ZERO_COUNT			11		// Zero 呼び出し回数
+#define	KS_COPY_COUNT			12		// Copy 呼び出し回数
+// ロック関係
+#define	KS_NEWLOCK_COUNT		13		// NewLock を呼び出した回数
+#define	KS_DELETELOCK_COUNT		14		// DeleteLock を呼び出した回数
+#define	KS_LOCK_COUNT			15		// Lock を呼び出した回数
+#define	KS_UNLOCK_COUNT			16		// Unlock を呼び出した回数
+#define	KS_CURRENT_LOCK_COUNT	17		// 現在の LOCK オブジェクト数
+#define	KS_CURRENT_LOCKED_COUNT	18		// 現在のロックされている LOCK オブジェクト数
+// カウンタ情報
+#define	KS_NEW_COUNTER_COUNT	19		// NewCounter を呼び出した回数
+#define	KS_DELETE_COUNTER_COUNT	20		// DeleteCounter を呼び出した回数
+#define	KS_INC_COUNT			21		// Inc を呼び出した回数
+#define	KS_DEC_COUNT			22		// Dec を呼び出した回数
+#define	KS_CURRENT_COUNT		23		// 現在のカウント数の合計
+// 参照カウンタ情報
+#define	KS_NEWREF_COUNT			24		// NewRef を呼び出した回数
+#define	KS_FREEREF_COUNT		72		// REF オブジェクトを削除した回数
+#define	KS_ADDREF_COUNT			25		// AddRef を呼び出した回数
+#define	KS_RELEASE_COUNT		26		// Release を呼び出した回数
+#define	KS_CURRENT_REF_COUNT	27		// 現在の REF オブジェクト数
+#define	KS_CURRENT_REFED_COUNT	28		// 現在の参照数の合計
+// バッファ情報
+#define	KS_NEWBUF_COUNT			29		// NewBuf を呼び出した回数
+#define	KS_FREEBUF_COUNT		30		// FreeBuf を呼び出した回数
+#define	KS_CURRENT_BUF_COUNT	31		// 現在の BUF オブジェクトの数
+#define	KS_READ_BUF_COUNT		32		// ReadBuf を呼び出した回数
+#define	KS_WRITE_BUF_COUNT		33		// WriteBuf を呼び出した回数
+#define	KS_ADJUST_BUFSIZE_COUNT	34		// バッファサイズを調整した回数
+#define	KS_SEEK_BUF_COUNT		35		// SeekBuf を呼び出した回数
+// FIFO 情報
+#define	KS_NEWFIFO_COUNT		36		// NewFifo を呼び出した回数
+#define	KS_FREEFIFO_COUNT		37		// FIFO オブジェクトを削除した回数
+#define	KS_READ_FIFO_COUNT		38		// ReadFifo を呼び出した回数
+#define	KS_WRITE_FIFO_COUNT		39		// WriteFifo を呼び出した回数
+#define	KS_PEEK_FIFO_COUNT		40		// PeekFifo を呼び出した回数
+// リスト関係
+#define	KS_NEWLIST_COUNT		41		// NewList を呼び出した回数
+#define	KS_FREELIST_COUNT		42		// LIST オブジェクトを削除した回数
+#define	KS_INSERT_COUNT			43		// Add を呼び出した回数
+#define	KS_DELETE_COUNT			44		// Delete を呼び出した回数
+#define	KS_SORT_COUNT			45		// Sort を呼び出した回数
+#define	KS_SEARCH_COUNT			46		// Search を呼び出した回数
+#define	KS_TOARRAY_COUNT		47		// ToArray を呼び出した回数
+// キュー関係
+#define	KS_NEWQUEUE_COUNT		48		// NewQueue を呼び出した回数
+#define	KS_FREEQUEUE_COUNT		49		// QUEUE オブジェクトを削除した回数
+#define	KS_PUSH_COUNT			50		// Push を呼び出した回数
+#define	KS_POP_COUNT			51		// POP を呼び出した回数
+// スタック関係
+#define	KS_NEWSK_COUNT			52		// NewSk を呼び出した回数
+#define	KS_FREESK_COUNT			53		// SK オブジェクトを削除した回数
+#define	KS_INSERT_QUEUE_COUNT	54		// InsertQueue を呼び出した回数
+#define	KS_GETNEXT_COUNT		55		// GetNext を呼び出した回数
+// カーネル関係
+#define	KS_GETTIME_COUNT		56		// 時刻を取得した回数
+#define	KS_GETTICK_COUNT		57		// システムタイマを取得した回数
+#define	KS_NEWTHREAD_COUNT		58		// NewThread を呼び出した回数
+#define	KS_FREETHREAD_COUNT		59		// THREAD オブジェクトを削除した回数
+#define	KS_WAITFORTHREAD_COUNT	60		// WaitForThread を呼び出した回数
+#define	KS_NEWEVENT_COUNT		61		// NewEvent を呼び出した回数
+#define	KS_FREEEVENT_COUNT		62		// EVENT オブジェクトを削除した回数
+#define	KS_WAIT_COUNT			63		// Wait を呼び出した回数
+#define	KS_SLEEPTHREAD_COUNT	64		// SleepThread を呼び出した回数
+// IO 関係
+#define	KS_IO_OPEN_COUNT		65		// ファイルを開いた回数
+#define	KS_IO_CREATE_COUNT		66		// ファイルを作成した回数
+#define	KS_IO_CLOSE_COUNT		67		// ファイルを閉じた回数
+#define	KS_IO_READ_COUNT		68		// ファイルから読み込んだ回数
+#define	KS_IO_WRITE_COUNT		69		// ファイルに書き込んだ回数
+#define	KS_IO_TOTAL_READ_SIZE	70		// ファイルから読み込んだ合計バイト数
+#define	KS_IO_TOTAL_WRITE_SIZE	71		// ファイルに書き込んだ合計バイト数
+// メモリプール関係
+#define	KS_MEMPOOL_MALLOC_COUNT	75		// メモリプールを確保した回数
+#define	KS_MEMPOOL_FREE_COUNT	73		// メモリプールを解放した回数
+#define	KS_MEMPOOL_CURRENT_NUM	74		// 現在のメモリプールの個数
+#define	KS_MEMPOOL_REALLOC_COUNT	76	// メモリプールを ReAlloc した回数
+
+
+// マクロ
+#define	IsDebug()		(g_debug)		// デバッグモード
+#define	IsMemCheck()	(g_memcheck)	// メモリチェックモード
+
+// 関数プロトタイプ
+void InitMayaqua(bool memcheck, bool debug, int argc, char **argv);
+void FreeMayaqua();
+bool IsNt();
+bool IsUnicode();
+void MayaquaDotNetMode();
+bool MayaquaIsDotNetMode();
+void MayaquaMinimalMode();
+bool MayaquaIsMinimalMode();
+bool Is64();
+bool Is32();
+bool IsIA64();
+bool IsX64();
+void InitKernelStatus();
+void FreeKernelStatus();
+void PrintDebugInformation();
+void LockKernelStatus(UINT id);
+void UnlockKernelStatus(UINT id);
+void PrintKernelStatus();
+void InitCommandLineStr(int argc, char **argv);
+void FreeCommandLineStr();
+void SetCommandLineStr(char *str);
+void SetCommandLineUniStr(wchar_t *str);
+char *GetCommandLineStr();
+wchar_t *GetCommandLineUniStr();
+void ParseCommandLineTokens();
+void FreeCommandLineTokens();
+TOKEN_LIST *GetCommandLineToken();
+UNI_TOKEN_LIST *GetCommandLineUniToken();
+void InitOsInfo();
+void FreeOsInfo();
+void Alert(char *msg, char *caption);
+void AlertW(wchar_t *msg, wchar_t *caption);
+OS_INFO *GetOsInfo();
+UINT GetOsType();
+void PrintOsInfo(OS_INFO *info);
+void CheckEndian();
+void CheckUnixTempDir();
+void TimeCheck();
+void SetHamMode();
+bool IsHamMode();
+void InitProbe();
+void FreeProbe();
+void EnableProbe(bool enable);
+bool IsProbeEnabled();
+void WriteProbe(char *filename, UINT line, char *str);
+void WriteProbeData(char *filename, UINT line, char *str, void *data, UINT size);
+USHORT CalcChecksum16(void *buf, UINT size);
+
+#ifdef	OS_WIN32
+// インポートライブラリ (for Win32)
+#pragma comment(lib, "Ws2_32.lib")
+#pragma comment(lib, "winmm.lib")
+#pragma comment(lib, "kernel32.lib")
+#pragma comment(lib, "user32.lib")
+#pragma comment(lib, "gdi32.lib")
+#pragma comment(lib, "shell32.lib")
+#pragma comment(lib, "comctl32.lib")
+#pragma comment(lib, "dbghelp.lib")
+#pragma comment(lib, "Iphlpapi.lib")
+#pragma comment(lib, "setupapi.lib")
+#pragma comment(lib, "version.lib")
+#pragma comment(lib, "Netapi32.lib")
+#pragma comment(lib, "shlwapi.lib")
+#pragma warning( disable : 4099 )
+#endif	// OS_WIN32
+
+// デバッグ用
+#ifndef	ENCRYPT_C
+//#define	Disconnect(s)		{Debug("Disconnect() Called: %s %u\n", __FILE__, __LINE__);Disconnect(s);}
+#endif
+
+
+#endif	// MAYAQUA_H
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Memory.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Memory.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Memory.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,2868 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Memory.c
+// メモリ管理プログラム
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <zlib/zlib.h>
+#include <Mayaqua/Mayaqua.h>
+
+#define	MEMORY_SLEEP_TIME		150
+#define	MEMORY_MAX_RETRY		30
+#define	INIT_BUF_SIZE			10240
+
+#define	FIFO_INIT_MEM_SIZE		4096
+#define	FIFO_REALLOC_MEM_SIZE	(65536 * 10)	// 絶妙な値
+#define FIFO_REALLOC_MEM_SIZE_SMALL	65536
+
+#define	INIT_NUM_RESERVED		32
+static UINT fifo_default_realloc_mem_size = FIFO_REALLOC_MEM_SIZE;
+
+// バイナリを検索
+UINT SearchBin(void *data, UINT data_start, UINT data_size, void *key, UINT key_size)
+{
+	UINT i;
+	// 引数チェック
+	if (data == NULL || key == NULL || key_size == 0 || data_size == 0 ||
+		(data_start >= data_size) || (data_start + key_size > data_size))
+	{
+		return INFINITE;
+	}
+
+	for (i = data_start;i < (data_size - key_size + 1);i++)
+	{
+		UCHAR *p = ((UCHAR *)data) + i;
+
+		if (Cmp(p, key, key_size) == 0)
+		{
+			return i;
+		}
+	}
+
+	return INFINITE;
+}
+
+// すぐにクラッシュする
+void CrashNow()
+{
+	// これでとりあえずどのような OS 上でもプロセスは落ちるはずである
+	while (true)
+	{
+		UINT r = Rand32();
+		UCHAR *c = (UCHAR *)r;
+
+		*c = Rand8();
+	}
+}
+
+// バッファを候補に変換
+LIST *BufToCandidate(BUF *b)
+{
+	LIST *o;
+	UINT i;
+	UINT num;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	num = ReadBufInt(b);
+	o = NewCandidateList();
+
+	for (i = 0;i < num;i++)
+	{
+		CANDIDATE *c;
+		wchar_t *s;
+		UINT64 sec64;
+		UINT len, size;
+		sec64 = ReadBufInt64(b);
+		len = ReadBufInt(b);
+		if (len >= 65536)
+		{
+			break;
+		}
+		size = (len + 1) * 2;
+		s = ZeroMalloc(size);
+		if (ReadBuf(b, s, size) != size)
+		{
+			Free(s);
+			break;
+		}
+		else
+		{
+			c = ZeroMalloc(sizeof(CANDIDATE));
+			c->LastSelectedTime = sec64;
+			c->Str = s;
+			Add(o, c);
+		}
+	}
+
+	Sort(o);
+	return o;
+}
+
+// 候補をバッファに変換
+BUF *CandidateToBuf(LIST *o)
+{
+	BUF *b;
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	b = NewBuf();
+	WriteBufInt(b, LIST_NUM(o));
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		CANDIDATE *c = LIST_DATA(o, i);
+		WriteBufInt64(b, c->LastSelectedTime);
+		WriteBufInt(b, UniStrLen(c->Str));
+		WriteBuf(b, c->Str, UniStrSize(c->Str));
+	}
+
+	SeekBuf(b, 0, 0);
+
+	return b;
+}
+
+// 候補の追加
+void AddCandidate(LIST *o, wchar_t *str, UINT num_max)
+{
+	UINT i;
+	bool exists;
+	// 引数チェック
+	if (o == NULL || str == NULL)
+	{
+		return;
+	}
+	if (num_max == 0)
+	{
+		num_max = 0x7fffffff;
+	}
+
+	// 文字列コピー
+	str = UniCopyStr(str);
+	UniTrim(str);
+
+	exists = false;
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		CANDIDATE *c = LIST_DATA(o, i);
+		if (UniStrCmpi(c->Str, str) == 0)
+		{
+			// 既存のものを発見したので時刻を更新する
+			c->LastSelectedTime = SystemTime64();
+			exists = true;
+			break;
+		}
+	}
+
+	if (exists == false)
+	{
+		// 新しく挿入する
+		CANDIDATE *c = ZeroMalloc(sizeof(CANDIDATE));
+		c->LastSelectedTime = SystemTime64();
+		c->Str = UniCopyStr(str);
+		Insert(o, c);
+	}
+
+	// 文字列解放
+	Free(str);
+
+	// 現在の候補数を調べて、num_max より多ければ
+	// 古いものから順に削除する
+	if (LIST_NUM(o) > num_max)
+	{
+		while (LIST_NUM(o) > num_max)
+		{
+			UINT index = LIST_NUM(o) - 1;
+			CANDIDATE *c = LIST_DATA(o, index);
+			Delete(o, c);
+			Free(c->Str);
+			Free(c);
+		}
+	}
+}
+
+// 候補の比較
+int ComapreCandidate(void *p1, void *p2)
+{
+	CANDIDATE *c1, *c2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	c1 = *(CANDIDATE **)p1;
+	c2 = *(CANDIDATE **)p2;
+	if (c1 == NULL || c2 == NULL)
+	{
+		return 0;
+	}
+	if (c1->LastSelectedTime > c2->LastSelectedTime)
+	{
+		return -1;
+	}
+	else if (c1->LastSelectedTime < c2->LastSelectedTime)
+	{
+		return 1;
+	}
+	else
+	{
+		return UniStrCmpi(c1->Str, c2->Str);
+	}
+}
+
+// 候補リストの解放
+void FreeCandidateList(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		CANDIDATE *c = LIST_DATA(o, i);
+		Free(c->Str);
+		Free(c);
+	}
+
+	ReleaseList(o);
+}
+
+// 新しい候補リストの作成
+LIST *NewCandidateList()
+{
+	return NewList(ComapreCandidate);
+}
+
+// 指定したアドレスがすべてゼロかどうか調べる
+bool IsZero(void *data, UINT size)
+{
+	UINT i;
+	UCHAR *c = (UCHAR *)data;
+	// 引数チェック
+	if (data == NULL || size == 0)
+	{
+		return true;
+	}
+
+	for (i = 0;i < size;i++)
+	{
+		if (c[i] != 0)
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// データを展開する
+UINT Uncompress(void *dst, UINT dst_size, void *src, UINT src_size)
+{
+	unsigned long dst_size_long = dst_size;
+	// 引数チェック
+	if (dst == NULL || dst_size_long == 0 || src == NULL)
+	{
+		return 0;
+	}
+
+	if (uncompress(dst, &dst_size_long, src, src_size) != Z_OK)
+	{
+		return 0;
+	}
+
+	return (UINT)dst_size_long;
+}
+
+// データを圧縮する
+UINT Compress(void *dst, UINT dst_size, void *src, UINT src_size)
+{
+	return CompressEx(dst, dst_size, src, src_size, Z_DEFAULT_COMPRESSION);
+}
+
+// データをオプション付きで圧縮する
+UINT CompressEx(void *dst, UINT dst_size, void *src, UINT src_size, UINT level)
+{
+	unsigned long dst_size_long = dst_size;
+	// 引数チェック
+	if (dst == NULL || dst_size_long == 0 || src == NULL)
+	{
+		return 0;
+	}
+
+	if (compress2(dst, &dst_size_long, src, src_size, (int)level) != Z_OK)
+	{
+		return 0;
+	}
+
+	return dst_size_long;
+}
+
+// src_size データを圧縮した場合の最大サイズを取得する
+UINT CalcCompress(UINT src_size)
+{
+	// あっ これは いい加減！
+	return src_size * 2 + 100;
+}
+
+// スタックの作成
+SK *NewSk()
+{
+	return NewSkEx(false);
+}
+SK *NewSkEx(bool no_compact)
+{
+	SK *s;
+
+	s = Malloc(sizeof(SK));
+	s->lock = NewLock();
+	s->ref = NewRef();
+	s->num_item = 0;
+	s->num_reserved = INIT_NUM_RESERVED;
+	s->p = Malloc(sizeof(void *) * s->num_reserved);
+	s->no_compact = no_compact;
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackNewObj(POINTER_TO_UINT64(s), "SK", 0);
+#endif	// DONT_USE_KERNEL_STATUS
+
+	// KS
+	KS_INC(KS_NEWSK_COUNT);
+
+	return s;
+}
+
+// スタックの解放
+void ReleaseSk(SK *s)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	if (Release(s->ref) == 0)
+	{
+		CleanupSk(s);
+	}
+}
+
+// スタックのクリーンアップ
+void CleanupSk(SK *s)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	// メモリ解放
+	Free(s->p);
+	DeleteLock(s->lock);
+	Free(s);
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackDeleteObj(POINTER_TO_UINT64(s));
+#endif	// DONT_USE_KERNEL_STATUS
+
+	// KS
+	KS_INC(KS_FREESK_COUNT);
+}
+
+// スタックのロック
+void LockSk(SK *s)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	Lock(s->lock);
+}
+
+// スタックのロック解除
+void UnlockSk(SK *s)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	Unlock(s->lock);
+}
+
+// スタックの Push
+void Push(SK *s, void *p)
+{
+	UINT i;
+	// 引数チェック
+	if (s == NULL || p == NULL)
+	{
+		return;
+	}
+
+	i = s->num_item;
+	s->num_item++;
+
+	// サイズ拡大
+	if (s->num_item > s->num_reserved)
+	{
+		s->num_reserved = s->num_reserved * 2;
+		s->p = ReAlloc(s->p, sizeof(void *) * s->num_reserved);
+	}
+	s->p[i] = p;
+
+	// KS
+	KS_INC(KS_PUSH_COUNT);
+}
+
+// スタックの Pop
+void *Pop(SK *s)
+{
+	void *ret;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return NULL;
+	}
+	if (s->num_item == 0)
+	{
+		return NULL;
+	}
+	ret = s->p[s->num_item - 1];
+	s->num_item--;
+
+	// サイズ縮小
+	if (s->no_compact == false)
+	{
+		// no_compact が true の場合は縮小しない
+		if ((s->num_item * 2) <= s->num_reserved)
+		{
+			if (s->num_reserved >= (INIT_NUM_RESERVED * 2))
+			{
+				s->num_reserved = s->num_reserved / 2;
+				s->p = ReAlloc(s->p, sizeof(void *) * s->num_reserved);
+			}
+		}
+	}
+
+	// KS
+	KS_INC(KS_POP_COUNT);
+
+	return ret;
+}
+
+// 1 つ取得
+void *GetNext(QUEUE *q)
+{
+	void *p = NULL;
+	// 引数チェック
+	if (q == NULL)
+	{
+		return NULL;
+	}
+
+	if (q->num_item == 0)
+	{
+		// アイテム無し
+		return NULL;
+	}
+
+	// FIFO から読み込む
+	ReadFifo(q->fifo, &p, sizeof(void *));
+	q->num_item--;
+
+	// KS
+	KS_INC(KS_GETNEXT_COUNT);
+
+	return p;
+}
+
+// キューに Int 型を挿入
+void InsertQueueInt(QUEUE *q, UINT value)
+{
+	UINT *p;
+	// 引数チェック
+	if (q == NULL)
+	{
+		return;
+	}
+
+	p = Clone(&value, sizeof(UINT));
+
+	InsertQueue(q, p);
+}
+
+// キューに挿入
+void InsertQueue(QUEUE *q, void *p)
+{
+	// 引数チェック
+	if (q == NULL || p == NULL)
+	{
+		return;
+	}
+
+	// FIFO に書き込む
+	WriteFifo(q->fifo, &p, sizeof(void *));
+
+	q->num_item++;
+
+	// KS
+	KS_INC(KS_INSERT_QUEUE_COUNT);
+}
+
+// キューのロック
+void LockQueue(QUEUE *q)
+{
+	// 引数チェック
+	if (q == NULL)
+	{
+		return;
+	}
+
+	Lock(q->lock);
+}
+
+// キューのロック解除
+void UnlockQueue(QUEUE *q)
+{
+	// 引数チェック
+	if (q == NULL)
+	{
+		return;
+	}
+
+	Unlock(q->lock);
+}
+
+// キューの解放
+void ReleaseQueue(QUEUE *q)
+{
+	// 引数チェック
+	if (q == NULL)
+	{
+		return;
+	}
+
+	if (q->ref == NULL || Release(q->ref) == 0)
+	{
+		CleanupQueue(q);
+	}
+}
+
+// キューのクリーンアップ
+void CleanupQueue(QUEUE *q)
+{
+	// 引数チェック
+	if (q == NULL)
+	{
+		return;
+	}
+
+	// メモリ解放
+	ReleaseFifo(q->fifo);
+	DeleteLock(q->lock);
+	Free(q);
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackDeleteObj(POINTER_TO_UINT64(q));
+#endif	// DONT_USE_KERNEL_STATUS
+
+	// KS
+	KS_INC(KS_FREEQUEUE_COUNT);
+}
+
+// キューの作成
+QUEUE *NewQueue()
+{
+	QUEUE *q;
+
+	q = ZeroMalloc(sizeof(QUEUE));
+	q->lock = NewLock();
+	q->ref = NewRef();
+	q->num_item = 0;
+	q->fifo = NewFifo();
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackNewObj(POINTER_TO_UINT64(q), "QUEUE", 0);
+#endif	// DONT_USE_KERNEL_STATUS
+
+	// KS
+	KS_INC(KS_NEWQUEUE_COUNT);
+
+	return q;
+}
+QUEUE *NewQueueFast()
+{
+	QUEUE *q;
+
+	q = ZeroMalloc(sizeof(QUEUE));
+	q->lock = NULL;
+	q->ref = NULL;
+	q->num_item = 0;
+	q->fifo = NewFifoFast();
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackNewObj(POINTER_TO_UINT64(q), "QUEUE", 0);
+#endif	// DONT_USE_KERNEL_STATUS
+
+	// KS
+	KS_INC(KS_NEWQUEUE_COUNT);
+
+	return q;
+}
+
+// リストに比較関数をセットする
+void SetCmp(LIST *o, COMPARE *cmp)
+{
+	// 引数チェック
+	if (o == NULL || cmp == NULL)
+	{
+		return;
+	}
+
+	if (o->cmp != cmp)
+	{
+		o->cmp = cmp;
+		o->sorted = false;
+	}
+}
+
+// リストのクローン
+LIST *CloneList(LIST *o)
+{
+	LIST *n = NewList(o->cmp);
+
+	// メモリ再確保
+	Free(n->p);
+	n->p = ToArray(o);
+	n->num_item = n->num_reserved = LIST_NUM(o);
+	n->sorted = o->sorted;
+
+	return n;
+}
+
+// リストを配列にコピー
+void CopyToArray(LIST *o, void *p)
+{
+	// 引数チェック
+	if (o == NULL || p == NULL)
+	{
+		return;
+	}
+
+	// KS
+	KS_INC(KS_TOARRAY_COUNT);
+
+	Copy(p, o->p, sizeof(void *) * o->num_item);
+}
+
+// リストを配列化する
+void *ToArray(LIST *o)
+{
+	return ToArrayEx(o, false);
+}
+void *ToArrayEx(LIST *o, bool fast)
+{
+	void *p;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	// メモリ確保
+	if (fast == false)
+	{
+		p = Malloc(sizeof(void *) * LIST_NUM(o));
+	}
+	else
+	{
+		p = MallocFast(sizeof(void *) * LIST_NUM(o));
+	}
+	// コピー
+	CopyToArray(o, p);
+
+	return p;
+}
+
+// リストのサーチ
+void *Search(LIST *o, void *target)
+{
+	void **ret;
+	// 引数チェック
+	if (o == NULL || target == NULL)
+	{
+		return NULL;
+	}
+	if (o->cmp == NULL)
+	{
+		return NULL;
+	}
+
+	// ソートのチェック
+	if (o->sorted == false)
+	{
+		// 未ソートなのでソートを行う
+		Sort(o);
+	}
+
+	// なんだ C ライブラリのバイナリサーチ関数を呼んでいるだけか
+	ret = (void **)bsearch(&target, o->p, o->num_item, sizeof(void *),
+		(int(*)(const void *, const void *))o->cmp);
+
+	// KS
+	KS_INC(KS_SEARCH_COUNT);
+
+	if (ret != NULL)
+	{
+		return *ret;
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+// リストに項目を挿入
+// 本当はもうちょっとましなデータ構造 & アルゴリズムにするべき
+void Insert(LIST *o, void *p)
+{
+	int low, high, middle;
+	UINT pos;
+	int i;
+	// 引数チェック
+	if (o == NULL || p == NULL)
+	{
+		return;
+	}
+
+	if (o->cmp == NULL)
+	{
+		// ソート関数が無い場合は単純に追加する
+		Add(o, p);
+		return;
+	}
+
+	// ソートされていない場合は直ちにソートする
+	if (o->sorted == false)
+	{
+		Sort(o);
+	}
+
+	low = 0;
+	high = LIST_NUM(o) - 1;
+
+	pos = INFINITE;
+
+	while (low <= high)
+	{
+		int ret;
+
+		middle = (low + high) / 2;
+		ret = o->cmp(&(o->p[middle]), &p);
+
+		if (ret == 0)
+		{
+			pos = middle;
+			break;
+		}
+		else if (ret > 0)
+		{
+			high = middle - 1;
+		}
+		else
+		{
+			low = middle + 1;
+		}
+	}
+
+	if (pos == INFINITE)
+	{
+		pos = low;
+	}
+
+	o->num_item++;
+	if (o->num_item > o->num_reserved)
+	{
+		o->num_reserved *= 2;
+		o->p = ReAlloc(o->p, sizeof(void *) * o->num_reserved);
+	}
+
+	if (LIST_NUM(o) >= 2)
+	{
+		for (i = (LIST_NUM(o) - 2);i >= (int)pos;i--)
+		{
+			o->p[i + 1] = o->p[i];
+		}
+	}
+
+	o->p[pos] = p;
+
+	// KS
+	KS_INC(KS_INSERT_COUNT);
+}
+
+// ソートフラグの設定
+void SetSortFlag(LIST *o, bool sorted)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	o->sorted = sorted;
+}
+
+// リストのソート
+void Sort(LIST *o)
+{
+	// 引数チェック
+	if (o == NULL || o->cmp == NULL)
+	{
+		return;
+	}
+
+	qsort(o->p, o->num_item, sizeof(void *), (int(*)(const void *, const void *))o->cmp);
+	o->sorted = true;
+
+	// KS
+	KS_INC(KS_SORT_COUNT);
+}
+
+// ある文字列項目がリスト内に存在しているかどうか調べる (Unicode 版)
+bool IsInListUniStr(LIST *o, wchar_t *str)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		wchar_t *s = LIST_DATA(o, i);
+
+		if (UniStrCmpi(s, str) == 0)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// リスト内のポインタを置換する
+bool ReplaceListPointer(LIST *o, void *oldptr, void *newptr)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL || oldptr == NULL || newptr == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		void *p = LIST_DATA(o, i);
+
+		if (p == oldptr)
+		{
+			o->p[i] = newptr;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// ある文字列項目がリスト内に存在しているかどうか調べる
+bool IsInListStr(LIST *o, char *str)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		char *s = LIST_DATA(o, i);
+
+		if (StrCmpi(s, str) == 0)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// リスト内を UINT 形式のポインタで走査してポインタを取得する
+void *ListKeyToPointer(LIST *o, UINT key)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL || key == 0)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		void *p = LIST_DATA(o, i);
+
+		if (POINTER_TO_KEY(p) == key)
+		{
+			return p;
+		}
+	}
+
+	return NULL;
+}
+
+// あるキーがリスト内に存在するかどうか調べる
+bool IsInListKey(LIST *o, UINT key)
+{
+	void *p;
+	// 引数チェック
+	if (o == NULL || key == 0)
+	{
+		return false;
+	}
+
+	p = ListKeyToPointer(o, key);
+	if (p == NULL)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ある項目がリスト内に存在するかどうか調べる
+bool IsInList(LIST *o, void *p)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL || p == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		void *q = LIST_DATA(o, i);
+		if (p == q)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// リストへの要素の追加
+void Add(LIST *o, void *p)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL || p == NULL)
+	{
+		return;
+	}
+
+	i = o->num_item;
+	o->num_item++;
+
+	if (o->num_item > o->num_reserved)
+	{
+		o->num_reserved = o->num_reserved * 2;
+		o->p = ReAlloc(o->p, sizeof(void *) * o->num_reserved);
+	}
+
+	o->p[i] = p;
+	o->sorted = false;
+
+	// KS
+	KS_INC(KS_INSERT_COUNT);
+}
+
+// リストからキーで指定した要素の削除
+bool DeleteKey(LIST *o, UINT key)
+{
+	void *p;
+	// 引数チェック
+	if (o == NULL || key == 0)
+	{
+		return false;
+	}
+
+	p = ListKeyToPointer(o, key);
+	if (p == NULL)
+	{
+		return false;
+	}
+
+	return Delete(o, p);
+}
+
+// リストから要素の削除
+bool Delete(LIST *o, void *p)
+{
+	UINT i, n;
+	// 引数チェック
+	if (o == NULL || p == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;i < o->num_item;i++)
+	{
+		if (o->p[i] == p)
+		{
+			break;
+		}
+	}
+	if (i == o->num_item)
+	{
+		return false;
+	}
+
+	n = i;
+	for (i = n;i < (o->num_item - 1);i++)
+	{
+		o->p[i] = o->p[i + 1];
+	}
+	o->num_item--;
+	if ((o->num_item * 2) <= o->num_reserved)
+	{
+		if (o->num_reserved > (INIT_NUM_RESERVED * 2))
+		{
+			o->num_reserved = o->num_reserved / 2;
+			o->p = ReAlloc(o->p, sizeof(void *) * o->num_reserved);
+		}
+	}
+
+	// KS
+	KS_INC(KS_DELETE_COUNT);
+
+	return true;
+}
+
+// リストからすべての要素の削除
+void DeleteAll(LIST *o)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	o->num_item = 0;
+	o->num_reserved = INIT_NUM_RESERVED;
+	o->p = ReAlloc(o->p, sizeof(void *) * INIT_NUM_RESERVED);
+}
+
+// リストのロック
+void LockList(LIST *o)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	Lock(o->lock);
+}
+
+// リストのロック解除
+void UnlockList(LIST *o)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	Unlock(o->lock);
+}
+
+// リストの解放
+void ReleaseList(LIST *o)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	if (o->ref == NULL || Release(o->ref) == 0)
+	{
+		CleanupList(o);
+	}
+}
+
+// リストのクリーンアップ
+void CleanupList(LIST *o)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	Free(o->p);
+	if (o->lock != NULL)
+	{
+		DeleteLock(o->lock);
+	}
+	Free(o);
+
+	// KS
+	KS_INC(KS_FREELIST_COUNT);
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackDeleteObj(POINTER_TO_UINT64(o));
+#endif	// DONT_USE_KERNEL_STATUS
+}
+
+// 文字列比較関数 (Unicode)
+int CompareUniStr(void *p1, void *p2)
+{
+	wchar_t *s1, *s2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	s1 = *(wchar_t **)p1;
+	s2 = *(wchar_t **)p2;
+
+	return UniStrCmp(s1, s2);
+}
+
+// 文字列をリストに挿入する
+bool InsertStr(LIST *o, char *str)
+{
+	// 引数チェック
+	if (o == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	if (Search(o, str) == NULL)
+	{
+		Insert(o, str);
+
+		return true;
+	}
+
+	return false;
+}
+
+// 文字列比較関数
+int CompareStr(void *p1, void *p2)
+{
+	char *s1, *s2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	s1 = *(char **)p1;
+	s2 = *(char **)p2;
+
+	return StrCmpi(s1, s2);
+}
+
+// 高速リスト (ロック無し) の作成
+LIST *NewListFast(COMPARE *cmp)
+{
+	return NewListEx(cmp, true);
+}
+
+// リストの作成
+LIST *NewList(COMPARE *cmp)
+{
+	return NewListEx(cmp, false);
+}
+LIST *NewListEx(COMPARE *cmp, bool fast)
+{
+	return NewListEx2(cmp, fast, false);
+}
+LIST *NewListEx2(COMPARE *cmp, bool fast, bool fast_malloc)
+{
+	LIST *o;
+
+	if (fast_malloc == false)
+	{
+		o = Malloc(sizeof(LIST));
+	}
+	else
+	{
+		o = MallocFast(sizeof(LIST));
+	}
+
+	if (fast == false)
+	{
+		o->lock = NewLock();
+		o->ref = NewRef();
+	}
+	else
+	{
+		o->lock = NULL;
+		o->ref = NULL;
+	}
+	o->num_item = 0;
+	o->num_reserved = INIT_NUM_RESERVED;
+
+	if (fast_malloc == false)
+	{
+		o->p = Malloc(sizeof(void *) * o->num_reserved);
+	}
+	else
+	{
+		o->p = MallocFast(sizeof(void *) * o->num_reserved);
+	}
+
+	o->cmp = cmp;
+	o->sorted = true;
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackNewObj(POINTER_TO_UINT64(o), "LIST", 0);
+#endif	//DONT_USE_KERNEL_STATUS
+
+	// KS
+	KS_INC(KS_NEWLIST_COUNT);
+
+	return o;
+}
+
+// FIFO から peek する
+UINT PeekFifo(FIFO *f, void *p, UINT size)
+{
+	UINT read_size;
+	if (f == NULL || size == 0)
+	{
+		return 0;
+	}
+
+	// KS
+	KS_INC(KS_PEEK_FIFO_COUNT);
+
+	read_size = MIN(size, f->size);
+	if (read_size == 0)
+	{
+		return 0;
+	}
+
+	if (p != NULL)
+	{
+		Copy(p, (UCHAR *)f->p + f->pos, read_size);
+	}
+
+	return read_size;
+}
+
+// FIFO から読み取る
+UINT ReadFifo(FIFO *f, void *p, UINT size)
+{
+	UINT read_size;
+	// 引数チェック
+	if (f == NULL || size == 0)
+	{
+		return 0;
+	}
+
+	read_size = MIN(size, f->size);
+	if (read_size == 0)
+	{
+		return 0;
+	}
+	if (p != NULL)
+	{
+		Copy(p, (UCHAR *)f->p + f->pos, read_size);
+	}
+	f->pos += read_size;
+	f->size -= read_size;
+
+	if (f->size == 0)
+	{
+		f->pos = 0;
+	}
+
+	// メモリの詰め直し
+	if (f->pos >= FIFO_INIT_MEM_SIZE &&
+		f->memsize >= f->realloc_mem_size &&
+		(f->memsize / 2) > f->size)
+	{
+		void *new_p;
+		UINT new_size;
+
+		new_size = MAX(f->memsize / 2, FIFO_INIT_MEM_SIZE);
+		new_p = Malloc(new_size);
+		Copy(new_p, (UCHAR *)f->p + f->pos, f->size);
+
+		Free(f->p);
+
+		f->memsize = new_size;
+		f->p = new_p;
+		f->pos = 0;
+	}
+
+	// KS
+	KS_INC(KS_READ_FIFO_COUNT);
+
+	return read_size;
+}
+
+// FIFO に書き込む
+void WriteFifo(FIFO *f, void *p, UINT size)
+{
+	UINT i, need_size;
+	bool realloc_flag;
+	// 引数チェック
+	if (f == NULL || size == 0)
+	{
+		return;
+	}
+
+	i = f->size;
+	f->size += size;
+	need_size = f->pos + f->size;
+	realloc_flag = false;
+
+	// メモリ拡張
+	while (need_size > f->memsize)
+	{
+		f->memsize = MAX(f->memsize, FIFO_INIT_MEM_SIZE) * 3;
+		realloc_flag = true;
+	}
+
+	if (realloc_flag)
+	{
+		f->p = ReAlloc(f->p, f->memsize);
+	}
+
+	// データ書き込み
+	if (p != NULL)
+	{
+		Copy((UCHAR *)f->p + f->pos + i, p, size);
+	}
+
+	// KS
+	KS_INC(KS_WRITE_FIFO_COUNT);
+}
+
+// FIFO のクリア
+void ClearFifo(FIFO *f)
+{
+	// 引数チェック
+	if (f == NULL)
+	{
+		return;
+	}
+
+	f->size = f->pos = 0;
+	f->memsize = FIFO_INIT_MEM_SIZE;
+	f->p = ReAlloc(f->p, f->memsize);
+}
+
+// FIFO のサイズ取得
+UINT FifoSize(FIFO *f)
+{
+	// 引数チェック
+	if (f == NULL)
+	{
+		return 0;
+	}
+
+	return f->size;
+}
+
+// FIFO のロック
+void LockFifo(FIFO *f)
+{
+	// 引数チェック
+	if (f == NULL)
+	{
+		return;
+	}
+
+	Lock(f->lock);
+}
+
+// FIFO のロック解除
+void UnlockFifo(FIFO *f)
+{
+	// 引数チェック
+	if (f == NULL)
+	{
+		return;
+	}
+
+	Unlock(f->lock);
+}
+
+// FIFO の解放
+void ReleaseFifo(FIFO *f)
+{
+	// 引数チェック
+	if (f == NULL)
+	{
+		return;
+	}
+
+	if (f->ref == NULL || Release(f->ref) == 0)
+	{
+		CleanupFifo(f);
+	}
+}
+
+// FIFO のクリーンアップ
+void CleanupFifo(FIFO *f)
+{
+	// 引数チェック
+	if (f == NULL)
+	{
+		return;
+	}
+
+	DeleteLock(f->lock);
+	Free(f->p);
+	Free(f);
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackDeleteObj(POINTER_TO_UINT64(f));
+#endif	//DONT_USE_KERNEL_STATUS
+
+	// KS
+	KS_INC(KS_FREEFIFO_COUNT);
+}
+
+// FIFO システムの初期化
+void InitFifo()
+{
+	fifo_default_realloc_mem_size = FIFO_REALLOC_MEM_SIZE;
+}
+
+// FIFO の作成
+FIFO *NewFifo()
+{
+	return NewFifoEx(0, false);
+}
+FIFO *NewFifoFast()
+{
+	return NewFifoEx(0, true);
+}
+FIFO *NewFifoEx(UINT realloc_mem_size, bool fast)
+{
+	FIFO *f;
+
+	// メモリ確保
+	f = Malloc(sizeof(FIFO));
+
+	if (fast == false)
+	{
+		f->lock = NewLock();
+		f->ref = NewRef();
+	}
+	else
+	{
+		f->lock = NULL;
+		f->ref = NULL;
+	}
+
+	f->size = f->pos = 0;
+	f->memsize = FIFO_INIT_MEM_SIZE;
+	f->p = Malloc(FIFO_INIT_MEM_SIZE);
+
+	if (realloc_mem_size == 0)
+	{
+		realloc_mem_size = fifo_default_realloc_mem_size;
+	}
+
+	f->realloc_mem_size = realloc_mem_size;
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackNewObj(POINTER_TO_UINT64(f), "FIFO", 0);
+#endif	// DONT_USE_KERNEL_STATUS
+
+	// KS
+	KS_INC(KS_NEWFIFO_COUNT);
+
+	return f;
+}
+
+// FIFO のデフォルトのメモリ再確保サイズを取得する
+UINT GetFifoDefaultReallocMemSize()
+{
+	return fifo_default_realloc_mem_size;
+}
+
+// FIFO のデフォルトのメモリ再確保サイズを設定する
+void SetFifoDefaultReallocMemSize(UINT size)
+{
+	if (size == 0)
+	{
+		size = FIFO_REALLOC_MEM_SIZE;
+	}
+
+	fifo_default_realloc_mem_size = size;
+}
+
+// バッファをファイルから読み込む
+BUF *FileToBuf(IO *o)
+{
+	UCHAR hash1[MD5_SIZE], hash2[MD5_SIZE];
+	UINT size;
+	void *buf;
+	BUF *b;
+
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	// サイズを読み込む
+	if (FileRead(o, &size, sizeof(size)) == false)
+	{
+		return NULL;
+	}
+	size = Endian32(size);
+
+	if (size > FileSize(o))
+	{
+		return NULL;
+	}
+
+	// ハッシュを読み込む
+	if (FileRead(o, hash1, sizeof(hash1)) == false)
+	{
+		return NULL;
+	}
+
+	// バッファを読み込む
+	buf = Malloc(size);
+	if (FileRead(o, buf, size) == false)
+	{
+		Free(buf);
+		return NULL;
+	}
+
+	// ハッシュをとる
+	Hash(hash2, buf, size, false);
+
+	// ハッシュを比較する
+	if (Cmp(hash1, hash2, sizeof(hash1)) != 0)
+	{
+		// ハッシュが異なる
+		Free(buf);
+		return NULL;
+	}
+
+	// バッファを作成する
+	b = NewBuf();
+	WriteBuf(b, buf, size);
+	Free(buf);
+	b->Current = 0;
+
+	return b;
+}
+
+// ダンプファイルをバッファに読み込む
+BUF *ReadDump(char *filename)
+{
+	IO *o;
+	BUF *b;
+	UINT size;
+	void *data;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return NULL;
+	}
+
+	o = FileOpen(filename, false);
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	size = FileSize(o);
+	data = Malloc(size);
+	FileRead(o, data, size);
+	FileClose(o);
+
+	b = NewBuf();
+	WriteBuf(b, data, size);
+	b->Current = 0;
+	Free(data);
+
+	return b;
+}
+BUF *ReadDumpW(wchar_t *filename)
+{
+	IO *o;
+	BUF *b;
+	UINT size;
+	void *data;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return NULL;
+	}
+
+	o = FileOpenW(filename, false);
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	size = FileSize(o);
+	data = Malloc(size);
+	FileRead(o, data, size);
+	FileClose(o);
+
+	b = NewBuf();
+	WriteBuf(b, data, size);
+	b->Current = 0;
+	Free(data);
+
+	return b;
+}
+
+// バッファ内容をファイルにダンプする
+bool DumpBuf(BUF *b, char *filename)
+{
+	IO *o;
+	// 引数チェック
+	if (b == NULL || filename == NULL)
+	{
+		return false;
+	}
+
+	o = FileCreate(filename);
+	if (o == NULL)
+	{
+		return false;
+	}
+	FileWrite(o, b->Buf, b->Size);
+	FileClose(o);
+
+	return true;
+}
+bool DumpBufW(BUF *b, wchar_t *filename)
+{
+	IO *o;
+	// 引数チェック
+	if (b == NULL || filename == NULL)
+	{
+		return false;
+	}
+
+	o = FileCreateW(filename);
+	if (o == NULL)
+	{
+		return false;
+	}
+	FileWrite(o, b->Buf, b->Size);
+	FileClose(o);
+
+	return true;
+}
+
+// バッファをファイルに書き込む
+bool BufToFile(IO *o, BUF *b)
+{
+	UCHAR hash[MD5_SIZE];
+	UINT size;
+
+	// 引数チェック
+	if (o == NULL || b == NULL)
+	{
+		return false;
+	}
+
+	// データをハッシュする
+	Hash(hash, b->Buf, b->Size, false);
+
+	size = Endian32(b->Size);
+
+	// サイズを書き込む
+	if (FileWrite(o, &size, sizeof(size)) == false)
+	{
+		return false;
+	}
+
+	// ハッシュを書き込む
+	if (FileWrite(o, hash, sizeof(hash)) == false)
+	{
+		return false;
+	}
+
+	// データを書き込む
+	if (FileWrite(o, b->Buf, b->Size) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// バッファの作成
+BUF *NewBuf()
+{
+	BUF *b;
+
+	// メモリ確保
+	b = Malloc(sizeof(BUF));
+	b->Buf = Malloc(INIT_BUF_SIZE);
+	b->Size = 0;
+	b->Current = 0;
+	b->SizeReserved = INIT_BUF_SIZE;
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackNewObj(POINTER_TO_UINT64(b), "BUF", 0);
+#endif	// DONT_USE_KERNEL_STATUS
+
+	// KS
+	KS_INC(KS_NEWBUF_COUNT);
+	KS_INC(KS_CURRENT_BUF_COUNT);
+
+	return b;
+}
+
+// バッファのクリア
+void ClearBuf(BUF *b)
+{
+	// 引数チェック
+	if (b == NULL)
+	{
+		return;
+	}
+
+	b->Size = 0;
+	b->Current = 0;
+}
+
+// バッファへ書き込み
+void WriteBuf(BUF *b, void *buf, UINT size)
+{
+	UINT new_size;
+	// 引数チェック
+	if (b == NULL || buf == NULL || size == 0)
+	{
+		return;
+	}
+
+	new_size = b->Current + size;
+	if (new_size > b->Size)
+	{
+		// サイズを調整する
+		AdjustBufSize(b, new_size);
+	}
+	if (b->Buf != NULL)
+	{
+		Copy((UCHAR *)b->Buf + b->Current, buf, size);
+	}
+	b->Current += size;
+	b->Size = new_size;
+
+	// KS
+	KS_INC(KS_WRITE_BUF_COUNT);
+}
+
+// バッファに文字列を追記
+void AddBufStr(BUF *b, char *str)
+{
+	// 引数チェック
+	if (b == NULL || str == NULL)
+	{
+		return;
+	}
+
+	WriteBuf(b, str, StrLen(str));
+}
+
+// バッファに 1 行書き込む
+void WriteBufLine(BUF *b, char *str)
+{
+	char *crlf = "\r\n";
+	// 引数チェック
+	if (b == NULL || str == NULL)
+	{
+		return;
+	}
+
+	WriteBuf(b, str, StrLen(str));
+	WriteBuf(b, crlf, StrLen(crlf));
+}
+
+// バッファに文字列を書き込む
+bool WriteBufStr(BUF *b, char *str)
+{
+	UINT len;
+	// 引数チェック
+	if (b == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	// 文字列長
+	len = StrLen(str);
+	if (WriteBufInt(b, len + 1) == false)
+	{
+		return false;
+	}
+
+	// 文字列本体
+	WriteBuf(b, str, len);
+
+	return true;
+}
+
+// バッファから文字列を読み込む
+bool ReadBufStr(BUF *b, char *str, UINT size)
+{
+	UINT len;
+	UINT read_size;
+	// 引数チェック
+	if (b == NULL || str == NULL || size == 0)
+	{
+		return false;
+	}
+
+	// 文字列長を読み込む
+	len = ReadBufInt(b);
+	if (len == 0)
+	{
+		return false;
+	}
+	len--;
+	if (len <= (size - 1))
+	{
+		size = len + 1;
+	}
+
+	read_size = MIN(len, (size - 1));
+
+	// 文字列本体を読み込む
+	if (ReadBuf(b, str, read_size) != read_size)
+	{
+		return false;
+	}
+	if (read_size < len)
+	{
+		ReadBuf(b, NULL, len - read_size);
+	}
+	str[read_size] = 0;
+
+	return true;
+}
+
+// バッファに 64 bit 整数を書き込む
+bool WriteBufInt64(BUF *b, UINT64 value)
+{
+	// 引数チェック
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	value = Endian64(value);
+
+	WriteBuf(b, &value, sizeof(UINT64));
+	return true;
+}
+
+// バッファに整数を書き込む
+bool WriteBufInt(BUF *b, UINT value)
+{
+	// 引数チェック
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	value = Endian32(value);
+
+	WriteBuf(b, &value, sizeof(UINT));
+	return true;
+}
+
+// バッファから 64bit 整数を読み込む
+UINT64 ReadBufInt64(BUF *b)
+{
+	UINT64 value;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return 0;
+	}
+
+	if (ReadBuf(b, &value, sizeof(UINT64)) != sizeof(UINT64))
+	{
+		return 0;
+	}
+	return Endian64(value);
+}
+
+// バッファから整数を読み込む
+UINT ReadBufInt(BUF *b)
+{
+	UINT value;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return 0;
+	}
+
+	if (ReadBuf(b, &value, sizeof(UINT)) != sizeof(UINT))
+	{
+		return 0;
+	}
+	return Endian32(value);
+}
+
+// バッファにバッファを書き込み
+void WriteBufBuf(BUF *b, BUF *bb)
+{
+	// 引数チェック
+	if (b == NULL || bb == NULL)
+	{
+		return;
+	}
+
+	WriteBuf(b, bb->Buf, bb->Size);
+}
+
+// バッファからバッファを読み込み
+BUF *ReadBufFromBuf(BUF *b, UINT size)
+{
+	BUF *ret;
+	UCHAR *data;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	data = Malloc(size);
+	if (ReadBuf(b, data, size) != size)
+	{
+		Free(data);
+		return NULL;
+	}
+
+	ret = NewBuf();
+	WriteBuf(ret, data, size);
+	SeekBuf(ret, 0, 0);
+
+	Free(data);
+
+	return ret;
+}
+
+// バッファから読み込み
+UINT ReadBuf(BUF *b, void *buf, UINT size)
+{
+	UINT size_read;
+	// 引数チェック
+	if (b == NULL || size == 0)
+	{
+		return 0;
+	}
+
+	if (b->Buf == NULL)
+	{
+		Zero(buf, size);
+		return 0;
+	}
+	size_read = size;
+	if ((b->Current + size) >= b->Size)
+	{
+		size_read = b->Size - b->Current;
+		if (buf != NULL)
+		{
+			Zero((UCHAR *)buf + size_read, size - size_read);
+		}
+	}
+
+	if (buf != NULL)
+	{
+		Copy(buf, (UCHAR *)b->Buf + b->Current, size_read);
+	}
+
+	b->Current += size_read;
+
+	// KS
+	KS_INC(KS_READ_BUF_COUNT);
+
+	return size_read;
+}
+
+// バッファサイズの調整
+void AdjustBufSize(BUF *b, UINT new_size)
+{
+	// 引数チェック
+	if (b == NULL)
+	{
+		return;
+	}
+
+	if (b->SizeReserved >= new_size)
+	{
+		return;
+	}
+
+	while (b->SizeReserved < new_size)
+	{
+		b->SizeReserved = b->SizeReserved * 2;
+	}
+	b->Buf = ReAlloc(b->Buf, b->SizeReserved);
+
+	// KS
+	KS_INC(KS_ADJUST_BUFSIZE_COUNT);
+}
+
+// バッファのシーク
+void SeekBuf(BUF *b, UINT offset, int mode)
+{
+	UINT new_pos;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return;
+	}
+
+	if (mode == 0)
+	{
+		// 絶対位置
+		new_pos = offset;
+	}
+	else
+	{
+		if (mode > 0)
+		{
+			// 右へ移動
+			new_pos = b->Current + offset;
+		}
+		else
+		{
+			// 左へ移動
+			if (b->Current >= offset)
+			{
+				new_pos = b->Current - offset;
+			}
+			else
+			{
+				new_pos = 0;
+			}
+		}
+	}
+	b->Current = MAKESURE(new_pos, 0, b->Size);
+
+	KS_INC(KS_SEEK_BUF_COUNT);
+}
+
+// バッファの解放
+void FreeBuf(BUF *b)
+{
+	// 引数チェック
+	if (b == NULL)
+	{
+		return;
+	}
+
+	// メモリ解放
+	Free(b->Buf);
+	Free(b);
+
+	// KS
+	KS_INC(KS_FREEBUF_COUNT);
+	KS_DEC(KS_CURRENT_BUF_COUNT);
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackDeleteObj(POINTER_TO_UINT64(b));
+#endif	// DONT_USE_KERNEL_STATUS
+}
+
+// Unicode 文字列のエンディアン変換
+void EndianUnicode(wchar_t *str)
+{
+	UINT i, len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+	len = UniStrLen(str);
+
+	for (i = 0;i < len;i++)
+	{
+		str[i] = Endian16(str[i]);
+	}
+}
+
+// エンディアン変換 16bit
+USHORT Endian16(USHORT src)
+{
+	int x = 1;
+	if (*((char *)&x))
+	{
+		return Swap16(src);
+	}
+	else
+	{
+		return src;
+	}
+}
+
+// エンディアン変換 32bit
+UINT Endian32(UINT src)
+{
+	int x = 1;
+	if (*((char *)&x))
+	{
+		return Swap32(src);
+	}
+	else
+	{
+		return src;
+	}
+}
+
+// エンディアン変換 64bit
+UINT64 Endian64(UINT64 src)
+{
+	int x = 1;
+	if (*((char *)&x))
+	{
+		return Swap64(src);
+	}
+	else
+	{
+		return src;
+	}
+}
+
+// 任意のデータのスワップ
+void Swap(void *buf, UINT size)
+{
+	UCHAR *tmp, *src;
+	UINT i;
+	// 引数チェック
+	if (buf == NULL || size == 0)
+	{
+		return;
+	}
+
+	src = (UCHAR *)buf;
+	tmp = Malloc(size);
+	for (i = 0;i < size;i++)
+	{
+		tmp[size - i - 1] = src[i];
+	}
+
+	Copy(buf, tmp, size);
+	Free(buf);
+}
+
+// 16bit スワップ
+USHORT Swap16(USHORT value)
+{
+	USHORT r;
+	// 汚いコード
+	((BYTE *)&r)[0] = ((BYTE *)&value)[1];
+	((BYTE *)&r)[1] = ((BYTE *)&value)[0];
+	return r;
+}
+
+// 32bit スワップ
+UINT Swap32(UINT value)
+{
+	UINT r;
+	// 汚いコード
+	((BYTE *)&r)[0] = ((BYTE *)&value)[3];
+	((BYTE *)&r)[1] = ((BYTE *)&value)[2];
+	((BYTE *)&r)[2] = ((BYTE *)&value)[1];
+	((BYTE *)&r)[3] = ((BYTE *)&value)[0];
+	return r;
+}
+
+// 64bit スワップ
+UINT64 Swap64(UINT64 value)
+{
+	UINT64 r;
+	// 汚いコード
+	((BYTE *)&r)[0] = ((BYTE *)&value)[7];
+	((BYTE *)&r)[1] = ((BYTE *)&value)[6];
+	((BYTE *)&r)[2] = ((BYTE *)&value)[5];
+	((BYTE *)&r)[3] = ((BYTE *)&value)[4];
+	((BYTE *)&r)[4] = ((BYTE *)&value)[3];
+	((BYTE *)&r)[5] = ((BYTE *)&value)[2];
+	((BYTE *)&r)[6] = ((BYTE *)&value)[1];
+	((BYTE *)&r)[7] = ((BYTE *)&value)[0];
+	return r;
+}
+
+// Base64 エンコード
+UINT Encode64(char *dst, char *src)
+{
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return 0;
+	}
+
+	return B64_Encode(dst, src, StrLen(src));
+}
+
+// Base64 デコード
+UINT Decode64(char *dst, char *src)
+{
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return 0;
+	}
+
+	return B64_Decode(dst, src, StrLen(src));
+}
+
+// Base64 エンコード
+int B64_Encode(char *set, char *source, int len)
+{
+	BYTE *src;
+	int i,j;
+	src = (BYTE *)source;
+	j = 0;
+	i = 0;
+	if (!len)
+	{
+		return 0;
+	}
+	while (TRUE)
+	{
+		if (i >= len)
+		{
+			return j;
+		}
+		if (set)
+		{
+			set[j] = B64_CodeToChar((src[i]) >> 2);
+		}
+		if (i + 1 >= len)
+		{
+			if (set)
+			{
+				set[j + 1] = B64_CodeToChar((src[i] & 0x03) << 4);
+				set[j + 2] = '=';
+				set[j + 3] = '=';
+			}
+			return j + 4;
+		}
+		if (set)
+		{
+			set[j + 1] = B64_CodeToChar(((src[i] & 0x03) << 4) + ((src[i + 1] >> 4)));
+		}
+		if (i + 2 >= len)
+		{
+			if (set)
+			{
+				set[j + 2] = B64_CodeToChar((src[i + 1] & 0x0f) << 2);
+				set[j + 3] = '=';
+			}
+			return j + 4;
+		}
+		if (set)
+		{
+			set[j + 2] = B64_CodeToChar(((src[i + 1] & 0x0f) << 2) + ((src[i + 2] >> 6)));
+			set[j + 3] = B64_CodeToChar(src[i + 2] & 0x3f);
+		}
+		i += 3;
+		j += 4;
+	}
+}
+
+// Base64 デコード
+int B64_Decode(char *set, char *source, int len)
+{
+	int i,j;
+	char a1,a2,a3,a4;
+	char *src;
+	int f1,f2,f3,f4;
+	src = source;
+	i = 0;
+	j = 0;
+	while (TRUE)
+	{
+		f1 = f2 = f3 = f4 = 0;
+		if (i >= len)
+		{
+			break;
+		}
+		f1 = 1;
+		a1 = B64_CharToCode(src[i]);
+		if (a1 == -1)
+		{
+			f1 = 0;
+		}
+		if (i >= len + 1)
+		{
+			a2 = 0;
+		}
+		else
+		{
+			a2 = B64_CharToCode(src[i + 1]);
+			f2 = 1;
+			if (a2 == -1)
+			{
+				f2 = 0;
+			}
+		}
+		if (i >= len + 2)
+		{
+			a3 = 0;
+		}
+		else
+		{
+			a3 = B64_CharToCode(src[i + 2]);
+			f3 = 1;
+			if (a3 == -1)
+			{
+				f3 = 0;
+			}
+		}
+		if (i >= len + 3)
+		{
+			a4 = 0;
+		}
+		else
+		{
+			a4 = B64_CharToCode(src[i + 3]);
+			f4 = 1;
+			if (a4 == -1)
+			{
+				f4 = 0;
+			}
+		}
+		if (f1 && f2)
+		{
+			if (set)
+			{
+				set[j] = (a1 << 2) + (a2 >> 4);
+			}
+			j++;
+		}
+		if (f2 && f3)
+		{
+			if (set)
+			{
+				set[j] = (a2 << 4) + (a3 >> 2);
+			}
+			j++;
+		}
+		if (f3 && f4)
+		{
+			if (set)
+			{
+				set[j] = (a3 << 6) + a4;
+			}
+			j++;
+		}
+		i += 4;
+	}
+	return j;
+}
+
+// Base64 - コードを文字に変換
+char B64_CodeToChar(BYTE c)
+{
+	BYTE r;
+	r = '=';
+	if (c <= 0x19)
+	{
+		r = c + 'A';
+	}
+	if (c >= 0x1a && c <= 0x33)
+	{
+		r = c - 0x1a + 'a';
+	}
+	if (c >= 0x34 && c <= 0x3d)
+	{
+		r = c - 0x34 + '0';
+	}
+	if (c == 0x3e)
+	{
+		r = '+';
+	}
+	if (c == 0x3f)
+	{
+		r = '/';
+	}
+	return r;
+}
+
+// Base64 - 文字をコードに変換
+char B64_CharToCode(char c)
+{
+	if (c >= 'A' && c <= 'Z')
+	{
+		return c - 'A';
+	}
+	if (c >= 'a' && c <= 'z')
+	{
+		return c - 'a' + 0x1a;
+	}
+	if (c >= '0' && c <= '9')
+	{
+		return c - '0' + 0x34;
+	}
+	if (c == '+')
+	{
+		return 0x3e;
+	}
+	if (c == '/')
+	{
+		return 0x3f;
+	}
+	if (c == '=')
+	{
+		return -1;
+	}
+	return 0;
+}
+
+// 高速な Malloc (現在未実装)
+// 実は小さなバッファをたくさんまとめておいてそれを動的に割り当てるコードを昔
+// 書いたのだが、Windows, Linux, Solaris で試しても普通の malloc() と比べて
+// ほとんど速度に影響がなかったので、やめにした。
+void *MallocFast(UINT size)
+{
+	return Malloc(size);
+}
+
+// Malloc
+void *Malloc(UINT size)
+{
+	return MallocEx(size, false);
+}
+void *MallocEx(UINT size, bool zero_clear_when_free)
+{
+	MEMTAG *tag;
+	UINT real_size;
+
+	real_size = CALC_MALLOCSIZE(size);
+
+	tag = InternalMalloc(real_size);
+
+	Zero(tag, sizeof(MEMTAG));
+	tag->Magic = MEMTAG_MAGIC;
+	tag->Size = size;
+	tag->ZeroFree = zero_clear_when_free;
+
+	return MEMTAG_TO_POINTER(tag);
+}
+
+// ReAlloc
+void *ReAlloc(void *addr, UINT size)
+{
+	MEMTAG *tag;
+	bool zerofree;
+	// 引数チェック
+	if (IS_NULL_POINTER(addr))
+	{
+		return NULL;
+	}
+
+	tag = POINTER_TO_MEMTAG(addr);
+	CheckMemTag(tag);
+
+	zerofree = tag->ZeroFree;
+
+	if (tag->Size == size)
+	{
+		// サイズ変更無し
+		return addr;
+	}
+	else
+	{
+		if (zerofree)
+		{
+			// サイズ変更有り (ゼロクリア必須)
+			void *new_p = MallocEx(size, true);
+
+			if (tag->Size <= size)
+			{
+				// サイズ拡大
+				Copy(new_p, addr, tag->Size);
+			}
+			else
+			{
+				// サイズ縮小
+				Copy(new_p, addr, size);
+			}
+
+			// 古いブロックの解放
+			Free(addr);
+
+			return new_p;
+		}
+		else
+		{
+			// サイズ変更有り
+			MEMTAG *tag2 = InternalReAlloc(tag, CALC_MALLOCSIZE(size));
+
+			Zero(tag2, sizeof(MEMTAG));
+			tag2->Magic = MEMTAG_MAGIC;
+			tag2->Size = size;
+
+			return MEMTAG_TO_POINTER(tag2);
+		}
+	}
+}
+
+// Free
+void Free(void *addr)
+{
+	MEMTAG *tag;
+	// 引数チェック
+	if (IS_NULL_POINTER(addr))
+	{
+		return;
+	}
+
+	tag = POINTER_TO_MEMTAG(addr);
+	CheckMemTag(tag);
+
+	if (tag->ZeroFree)
+	{
+		// ゼロクリア
+		Zero(addr, tag->Size);
+	}
+
+	// メモリ解放
+	tag->Magic = 0;
+	InternalFree(tag);
+}
+
+// memtag をチェック
+void CheckMemTag(MEMTAG *tag)
+{
+#ifndef	DONT_CHECK_HEAP
+	// 引数チェック
+	if (tag == NULL)
+	{
+		AbortExitEx("CheckMemTag: tag == NULL");
+		return;
+	}
+
+	if (tag->Magic != MEMTAG_MAGIC)
+	{
+		AbortExitEx("CheckMemTag: tag->Magic != MEMTAG_MAGIC");
+		return;
+	}
+#endif	// DONT_CHECK_HEAP
+}
+
+// ZeroMalloc
+void *ZeroMalloc(UINT size)
+{
+	return ZeroMallocEx(size, false);
+}
+void *ZeroMallocEx(UINT size, bool zero_clear_when_free)
+{
+	void *p = MallocEx(size, zero_clear_when_free);
+	Zero(p, size);
+	return p;
+}
+void *ZeroMallocFast(UINT size)
+{
+	void *p = MallocFast(size);
+	Zero(p, size);
+	return p;
+}
+
+// メモリ確保
+void *InternalMalloc(UINT size)
+{
+	void *addr;
+	UINT retry = 0;
+	size = MORE(size, 1);
+
+	// KS
+	KS_INC(KS_MALLOC_COUNT);
+	KS_INC(KS_TOTAL_MEM_COUNT);
+	KS_ADD(KS_TOTAL_MEM_SIZE, size);
+	KS_INC(KS_CURRENT_MEM_COUNT);
+
+	// メモリが確保されるまで試行する
+	while (true)
+	{
+		if ((retry++) > MEMORY_MAX_RETRY)
+		{
+			AbortExitEx("InternalMalloc: error: malloc() failed.\n\n");
+		}
+		addr = OSMemoryAlloc(size);
+		if (addr != NULL)
+		{
+			break;
+		}
+
+		OSSleep(MEMORY_SLEEP_TIME);
+	}
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackNewObj(POINTER_TO_UINT64(addr), "MEM", size);
+#endif	//DONT_USE_KERNEL_STATUS
+
+	return addr;
+}
+
+// メモリ解放
+void InternalFree(void *addr)
+{
+	// 引数チェック
+	if (addr == NULL)
+	{
+		return;
+	}
+
+	// KS
+	KS_DEC(KS_CURRENT_MEM_COUNT);
+	KS_INC(KS_FREE_COUNT);
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackDeleteObj(POINTER_TO_UINT64(addr));
+#endif	// DONT_USE_KERNEL_STATUS
+
+	// メモリ解放
+	OSMemoryFree(addr);
+}
+
+// メモリ再確保
+void *InternalReAlloc(void *addr, UINT size)
+{
+	void *new_addr;
+	UINT retry = 0;
+	size = MORE(size, 1);
+
+	// KS
+	KS_INC(KS_REALLOC_COUNT);
+	KS_ADD(KS_TOTAL_MEM_SIZE, size);
+
+	// メモリが確保されるまで試行する
+	while (true)
+	{
+		if ((retry++) > MEMORY_MAX_RETRY)
+		{
+			AbortExitEx("InternalReAlloc: error: realloc() failed.\n\n");
+		}
+		new_addr = OSMemoryReAlloc(addr, size);
+		if (new_addr != NULL)
+		{
+			break;
+		}
+
+		OSSleep(MEMORY_SLEEP_TIME);
+	}
+
+#ifndef	DONT_USE_KERNEL_STATUS
+	TrackChangeObjSize((DWORD)addr, size, (DWORD)new_addr);
+#endif	// DONT_USE_KERNEL_STATUS
+
+	return new_addr;
+}
+
+// メモリ領域のクローン
+void *Clone(void *addr, UINT size)
+{
+	void *ret;
+	// 引数チェック
+	if (addr == NULL)
+	{
+		return NULL;
+	}
+
+	ret = Malloc(size);
+	Copy(ret, addr, size);
+
+	return ret;
+}
+
+// メモリコピー
+void Copy(void *dst, void *src, UINT size)
+{
+	// 引数チェック
+	if (dst == NULL || src == NULL || size == 0 || dst == src)
+	{
+		return;
+	}
+
+	// KS
+	KS_INC(KS_COPY_COUNT);
+
+	memcpy(dst, src, size);
+}
+
+// メモリ比較
+int Cmp(void *p1, void *p2, UINT size)
+{
+	// 引数チェック
+	if (p1 == NULL || p2 == NULL || size == 0)
+	{
+		return 0;
+	}
+
+	return memcmp(p1, p2, (size_t)size);
+}
+
+// メモリのゼロクリア
+void Zero(void *addr, UINT size)
+{
+	ZeroMem(addr, size);
+}
+void ZeroMem(void *addr, UINT size)
+{
+	// 引数チェック
+	if (addr == NULL || size == 0)
+	{
+		return;
+	}
+
+	// KS
+	KS_INC(KS_ZERO_COUNT);
+
+	memset(addr, 0, size);
+}
+
+// 文字列マップエントリの比較
+int StrMapCmp(void *p1, void *p2)
+{
+	STRMAP_ENTRY *s1, *s2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	s1 = *(STRMAP_ENTRY **)p1;
+	s2 = *(STRMAP_ENTRY **)p2;
+	if (s1 == NULL || s2 == NULL)
+	{
+		return 0;
+	}
+	return StrCmpi(s1->Name, s2->Name);
+}
+
+// 文字列マップ（文字列で検索できるデータ）の作成
+LIST *NewStrMap()
+{
+	return NewList(StrMapCmp);
+}
+
+// 文字列マップの検索
+void *StrMapSearch(LIST *map, char *key)
+{
+	STRMAP_ENTRY tmp, *result;
+	tmp.Name = key;
+	result = (STRMAP_ENTRY*)Search(map, &tmp);
+	if(result != NULL)
+	{
+		return result->Value;
+	}
+	return NULL;
+}
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Memory.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Memory.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Memory.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,325 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Memory.h
+// Memory.c のヘッダ
+
+#ifndef	MEMORY_H
+#define	MEMORY_H
+
+// 一度にカーネルに渡すことができるメモリサイズ
+#define	MAX_SEND_BUF_MEM_SIZE				(10 * 1024 * 1024)
+
+// メモリタグ用マジックナンバー
+#define	MEMTAG_MAGIC						0x49414449
+
+#define	CALC_MALLOCSIZE(size)				((MAX(size, 1)) + sizeof(MEMTAG))
+#define	MEMTAG_TO_POINTER(p)				((void *)(((UCHAR *)(p)) + sizeof(MEMTAG)))
+#define	POINTER_TO_MEMTAG(p)				((MEMTAG *)(((UCHAR *)(p)) - sizeof(MEMTAG)))
+#define	IS_NULL_POINTER(p)					(((p) == NULL) || ((POINTER_TO_UINT64(p) == (UINT64)sizeof(MEMTAG))))
+
+// メモリプールの 1 ブロックの固定サイズ
+#define	MEMPOOL_MAX_SIZE					3000
+
+
+// メモリタグ
+struct MEMTAG
+{
+	UINT Magic;
+	UINT Size;
+	bool ZeroFree;
+	UINT Padding;
+};
+
+// バッファ
+struct BUF
+{
+	void *Buf;
+	UINT Size;
+	UINT SizeReserved;
+	UINT Current;
+};
+
+// FIFO
+struct FIFO
+{
+	REF *ref;
+	LOCK *lock;
+	void *p;
+	UINT pos, size, memsize;
+	UINT realloc_mem_size;
+};
+
+// リスト
+struct LIST
+{
+	REF *ref;
+	UINT num_item, num_reserved;
+	void **p;
+	LOCK *lock;
+	COMPARE *cmp;
+	bool sorted;
+};
+
+// キュー
+struct QUEUE
+{
+	REF *ref;
+	UINT num_item;
+	FIFO *fifo;
+	LOCK *lock;
+};
+
+// スタック
+struct SK
+{
+	REF *ref;
+	UINT num_item, num_reserved;
+	void **p;
+	LOCK *lock;
+	bool no_compact;
+};
+
+// 候補リスト
+struct CANDIDATE
+{
+	wchar_t *Str;						// 文字列
+	UINT64 LastSelectedTime;			// 最後に選択された日時
+};
+
+struct STRMAP_ENTRY
+{
+	char *Name;
+	void *Value;
+};
+
+// マクロ
+#define	LIST_DATA(o, i)		(((o) != NULL) ? ((o)->p[(i)]) : NULL)
+#define	LIST_NUM(o)			(((o) != NULL) ? (o)->num_item : 0)
+
+
+// 関数プロトタイプ
+LIST *NewCandidateList();
+void FreeCandidateList(LIST *o);
+int ComapreCandidate(void *p1, void *p2);
+void AddCandidate(LIST *o, wchar_t *str, UINT num_max);
+BUF *CandidateToBuf(LIST *o);
+LIST *BufToCandidate(BUF *b);
+
+void *Malloc(UINT size);
+void *MallocEx(UINT size, bool zero_clear_when_free);
+void *MallocFast(UINT size);
+void *ZeroMalloc(UINT size);
+void *ZeroMallocFast(UINT size);
+void *ZeroMallocEx(UINT size, bool zero_clear_when_free);
+void *ReAlloc(void *addr, UINT size);
+void Free(void *addr);
+void CheckMemTag(MEMTAG *tag);
+
+void *InternalMalloc(UINT size);
+void *InternalReAlloc(void *addr, UINT size);
+void InternalFree(void *addr);
+
+void Copy(void *dst, void *src, UINT size);
+int Cmp(void *p1, void *p2, UINT size);
+void ZeroMem(void *addr, UINT size);
+void Zero(void *addr, UINT size);
+void *Clone(void *addr, UINT size);
+
+char B64_CodeToChar(BYTE c);
+char B64_CharToCode(char c);
+int B64_Encode(char *set, char *source, int len);
+int B64_Decode(char *set, char *source, int len);
+UINT Encode64(char *dst, char *src);
+UINT Decode64(char *dst, char *src);
+
+void Swap(void *buf, UINT size);
+USHORT Swap16(USHORT value);
+UINT Swap32(UINT value);
+UINT64 Swap64(UINT64 value);
+USHORT Endian16(USHORT src);
+UINT Endian32(UINT src);
+UINT64 Endian64(UINT64 src);
+void EndianUnicode(wchar_t *str);
+
+BUF *NewBuf();
+void ClearBuf(BUF *b);
+void WriteBuf(BUF *b, void *buf, UINT size);
+void WriteBufBuf(BUF *b, BUF *bb);
+UINT ReadBuf(BUF *b, void *buf, UINT size);
+BUF *ReadBufFromBuf(BUF *b, UINT size);
+void AdjustBufSize(BUF *b, UINT new_size);
+void SeekBuf(BUF *b, UINT offset, int mode);
+void FreeBuf(BUF *b);
+bool BufToFile(IO *o, BUF *b);
+BUF *FileToBuf(IO *o);
+UINT ReadBufInt(BUF *b);
+UINT64 ReadBufInt64(BUF *b);
+bool WriteBufInt(BUF *b, UINT value);
+bool WriteBufInt64(BUF *b, UINT64 value);
+bool ReadBufStr(BUF *b, char *str, UINT size);
+bool WriteBufStr(BUF *b, char *str);
+void WriteBufLine(BUF *b, char *str);
+void AddBufStr(BUF *b, char *str);
+bool DumpBuf(BUF *b, char *filename);
+bool DumpBufW(BUF *b, wchar_t *filename);
+BUF *ReadDump(char *filename);
+BUF *ReadDumpW(wchar_t *filename);
+
+UINT PeekFifo(FIFO *f, void *p, UINT size);
+UINT ReadFifo(FIFO *f, void *p, UINT size);
+void WriteFifo(FIFO *f, void *p, UINT size);
+void ClearFifo(FIFO *f);
+UINT FifoSize(FIFO *f);
+void LockFifo(FIFO *f);
+void UnlockFifo(FIFO *f);
+void ReleaseFifo(FIFO *f);
+void CleanupFifo(FIFO *f);
+FIFO *NewFifo();
+FIFO *NewFifoFast();
+FIFO *NewFifoEx(UINT realloc_mem_size, bool fast);
+void InitFifo();
+UINT GetFifoDefaultReallocMemSize();
+void SetFifoDefaultReallocMemSize(UINT size);
+
+void *Search(LIST *o, void *target);
+void Sort(LIST *o);
+void Add(LIST *o, void *p);
+void Insert(LIST *o, void *p);
+bool Delete(LIST *o, void *p);
+bool DeleteKey(LIST *o, UINT key);
+void DeleteAll(LIST *o);
+void LockList(LIST *o);
+void UnlockList(LIST *o);
+void ReleaseList(LIST *o);
+void CleanupList(LIST *o);
+LIST *NewList(COMPARE *cmp);
+LIST *NewListFast(COMPARE *cmp);
+LIST *NewListEx(COMPARE *cmp, bool fast);
+LIST *NewListEx2(COMPARE *cmp, bool fast, bool fast_malloc);
+void CopyToArray(LIST *o, void *p);
+void *ToArray(LIST *o);
+void *ToArrayEx(LIST *o, bool fast);
+LIST *CloneList(LIST *o);
+void SetCmp(LIST *o, COMPARE *cmp);
+void SetSortFlag(LIST *o, bool sorted);
+int CompareStr(void *p1, void *p2);
+bool InsertStr(LIST *o, char *str);
+int CompareUniStr(void *p1, void *p2);
+bool IsInList(LIST *o, void *p);
+bool IsInListKey(LIST *o, UINT key);
+void *ListKeyToPointer(LIST *o, UINT key);
+bool IsInListStr(LIST *o, char *str);
+bool IsInListUniStr(LIST *o, wchar_t *str);
+bool ReplaceListPointer(LIST *o, void *oldptr, void *newptr);
+
+void *GetNext(QUEUE *q);
+void InsertQueue(QUEUE *q, void *p);
+void InsertQueueInt(QUEUE *q, UINT value);
+void LockQueue(QUEUE *q);
+void UnlockQueue(QUEUE *q);
+void ReleaseQueue(QUEUE *q);
+void CleanupQueue(QUEUE *q);
+QUEUE *NewQueue();
+QUEUE *NewQueueFast();
+
+SK *NewSk();
+SK *NewSkEx(bool no_compact);
+void ReleaseSk(SK *s);
+void CleanupSk(SK *s);
+void LockSk(SK *s);
+void UnlockSk(SK *s);
+void Push(SK *s, void *p);
+void *Pop(SK *s);
+
+UINT Uncompress(void *dst, UINT dst_size, void *src, UINT src_size);
+UINT Compress(void *dst, UINT dst_size, void *src, UINT src_size);
+UINT CompressEx(void *dst, UINT dst_size, void *src, UINT src_size, UINT level);
+UINT CalcCompress(UINT src_size);
+
+bool IsZero(void *data, UINT size);
+
+void Crash();
+
+LIST *NewStrMap();
+void *StrMapSearch(LIST *map, char *key);
+
+UINT SearchBin(void *data, UINT data_start, UINT data_size, void *key, UINT key_size);
+void CrashNow();
+
+#endif	// MEMORY_H
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Microsoft.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Microsoft.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Microsoft.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,12112 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Microsoft.c
+// Microsoft Windows 用コード
+// (Windows 以外の環境ではコンパイルされない)
+
+#ifdef	WIN32
+
+#define	MICROSOFT_C
+
+typedef enum    _PNP_VETO_TYPE {
+    PNP_VetoTypeUnknown,            // Name is unspecified
+    PNP_VetoLegacyDevice,           // Name is an Instance Path
+    PNP_VetoPendingClose,           // Name is an Instance Path
+    PNP_VetoWindowsApp,             // Name is a Module
+    PNP_VetoWindowsService,         // Name is a Service
+    PNP_VetoOutstandingOpen,        // Name is an Instance Path
+    PNP_VetoDevice,                 // Name is an Instance Path
+    PNP_VetoDriver,                 // Name is a Driver Service Name
+    PNP_VetoIllegalDeviceRequest,   // Name is an Instance Path
+    PNP_VetoInsufficientPower,      // Name is unspecified
+    PNP_VetoNonDisableable,         // Name is an Instance Path
+    PNP_VetoLegacyDriver,           // Name is a Service
+    PNP_VetoInsufficientRights      // Name is unspecified
+}   PNP_VETO_TYPE, *PPNP_VETO_TYPE;
+
+#define	_WIN32_IE			0x0600
+#define	_WIN32_WINNT		0x0502
+#define	WINVER				0x0502
+#define   SECURITY_WIN32
+#include <winsock2.h>
+#include <windows.h>
+#include <Wintrust.h>
+#include <Softpub.h>
+#include <Iphlpapi.h>
+#include <tlhelp32.h>
+#include <wincon.h>
+#include <Nb30.h>
+#include <shlobj.h>
+#include <commctrl.h>
+#include <Dbghelp.h>
+#include <setupapi.h>
+#include <regstr.h>
+#include <process.h>
+#include <psapi.h>
+#include <wtsapi32.h>
+#include <security.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+#include <cfgmgr32.h>
+#include <sddl.h>
+#include <Aclapi.h>
+
+
+static MS *ms = NULL;
+
+// 関数プロトタイプ
+UINT MsgBox(HWND hWnd, UINT flag, wchar_t *msg);
+UINT MsgBoxEx(HWND hWnd, UINT flag, wchar_t *msg, ...);
+void ShowTcpIpConfigUtil(HWND hWnd, bool util_mode);
+void CmTraffic(HWND hWnd);
+void CnStart();
+void InitCedar();
+void FreeCedar();
+void InitWinUi(wchar_t *software_name, char *font, UINT fontsize);
+void FreeWinUi();
+
+// グローバル変数
+void *ms_critical_section = NULL;
+UINT64 ms_uint64_1 = 0;
+
+// アダプタリスト関係
+static LOCK *lock_adapter_list = NULL;
+static MS_ADAPTER_LIST *last_adapter_list = NULL;
+
+// サービス関係
+static SERVICE_STATUS_HANDLE ssh = NULL;
+static SERVICE_STATUS status;
+static char g_service_name[MAX_SIZE];
+static SERVICE_FUNCTION *g_start, *g_stop;
+static bool exiting = false;
+static bool wnd_end;
+static bool is_usermode = false;
+static HICON tray_icon;
+static NOTIFYICONDATA nid;
+static NOTIFYICONDATAW nid_nt;
+static bool service_for_9x_mode = false;
+static THREAD *starter_thread = NULL;
+static EVENT *server_stopped_event = NULL;
+static THREAD *service_stopper_thread = NULL;
+static bool tray_inited = false;
+static HWND hWndUsermode = NULL;
+
+// [ネットワーク接続] を開くためのショートカット (最新版では未使用)
+static UCHAR network_connection_link[] =
+{
+	0x4C, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x46, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x14, 0x00, 
+	0x1F, 0x50, 0xE0, 0x4F, 0xD0, 0x20, 0xEA, 0x3A, 0x69, 0x10, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 
+	0x30, 0x9D, 0x14, 0x00, 0x2E, 0x00, 0x20, 0x20, 0xEC, 0x21, 0xEA, 0x3A, 0x69, 0x10, 0xA2, 0xDD, 
+	0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D, 0x14, 0x00, 0x70, 0x00, 0xC7, 0xAC, 0x07, 0x70, 0x02, 0x32, 
+	0xD1, 0x11, 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+};
+
+// Windows Vista 関係の新しいセキュリティ構造体等
+#if	0
+typedef struct _TOKEN_MANDATORY_LABEL
+{
+	SID_AND_ATTRIBUTES Label;
+} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
+#endif
+
+#define SE_GROUP_INTEGRITY                 (0x00000020L)
+
+typedef enum _TOKEN_INFORMATION_CLASS_VISTA
+{
+	VistaTokenUser = 1,
+	VistaTokenGroups,
+	VistaTokenPrivileges,
+	VistaTokenOwner,
+	VistaTokenPrimaryGroup,
+	VistaTokenDefaultDacl,
+	VistaTokenSource,
+	VistaTokenType,
+	VistaTokenImpersonationLevel,
+	VistaTokenStatistics,
+	VistaTokenRestrictedSids,
+	VistaTokenSessionId,
+	VistaTokenGroupsAndPrivileges,
+	VistaTokenSessionReference,
+	VistaTokenSandBoxInert,
+	VistaTokenAuditPolicy,
+	VistaTokenOrigin,
+	VistaTokenElevationType,
+	VistaTokenLinkedToken,
+	VistaTokenElevation,
+	VistaTokenHasRestrictions,
+	VistaTokenAccessInformation,
+	VistaTokenVirtualizationAllowed,
+	VistaTokenVirtualizationEnabled,
+	VistaTokenIntegrityLevel,
+	VistaTokenUIAccess,
+	VistaTokenMandatoryPolicy,
+	VistaTokenLogonSid,
+	VistaMaxTokenInfoClass
+} TOKEN_INFORMATION_CLASS_VISTA, *PTOKEN_INFORMATION_CLASS_VISTA;
+
+// エラーを表示しないモードにする
+void MsSetErrorModeToSilent()
+{
+	SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
+}
+
+// ファイル情報の取得
+bool MsGetFileInformation(void *h, void *info)
+{
+	// 引数チェック
+	if (h == INVALID_HANDLE_VALUE || info == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		return false;
+	}
+
+	if (ms->nt->GetFileInformationByHandle == NULL)
+	{
+		return false;
+	}
+
+	return ms->nt->GetFileInformationByHandle(h, info);
+}
+
+// プロセスのシャットダウンパラメータの設定
+void MsSetShutdownParameters(UINT level, UINT flag)
+{
+	if (MsIsNt() == false)
+	{
+		return;
+	}
+
+	if (ms->nt == false || ms->nt->SetProcessShutdownParameters == NULL)
+	{
+		return;
+	}
+
+	ms->nt->SetProcessShutdownParameters(level, flag);
+}
+
+// OS のバージョンが Windows XP または Windows Vista 以降かどうか取得する
+bool MsIsWinXPOrWinVista()
+{
+	OS_INFO *info = GetOsInfo();
+	if (info == NULL)
+	{
+		return false;
+	}
+
+	if (OS_IS_WINDOWS_NT(info->OsType) == false)
+	{
+		return false;
+	}
+
+	if (GET_KETA(info->OsType, 100) >= 3)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// イベントログに書き込む
+bool MsWriteEventLog(void *p, UINT type, wchar_t *str)
+{
+	MS_EVENTLOG *g = (MS_EVENTLOG *)p;
+	wchar_t *strings[2];
+	UINT id = 0;
+	UINT typeapi = 0;
+	// 引数チェック
+	if (g == NULL || type >= 5 || str == NULL)
+	{
+		return false;
+	}
+
+	strings[0] = str;
+
+	switch (type)
+	{
+	case MS_EVENTLOG_TYPE_INFORMATION:
+		id = MS_RC_EVENTLOG_TYPE_INFORMATION;
+		typeapi = EVENTLOG_INFORMATION_TYPE;
+		break;
+
+	case MS_EVENTLOG_TYPE_WARNING:
+		id = MS_RC_EVENTLOG_TYPE_WARNING;
+		typeapi = EVENTLOG_WARNING_TYPE;
+		break;
+
+	case MS_EVENTLOG_TYPE_ERROR:
+		id = MS_RC_EVENTLOG_TYPE_ERROR;
+		typeapi = EVENTLOG_ERROR_TYPE;
+		break;
+	}
+
+	return ms->nt->ReportEventW(g->hEventLog, typeapi, 0, id, NULL, 1, 0, strings, NULL);
+}
+
+// イベントログの解放
+void MsFreeEventLog(void *p)
+{
+	MS_EVENTLOG *g = (MS_EVENTLOG *)p;
+	// 引数チェック
+	if (g == NULL)
+	{
+		return;
+	}
+
+	ms->nt->DeregisterEventSource(g->hEventLog);
+
+	Free(g);
+}
+
+// イベントログの初期化
+void *MsInitEventLog(wchar_t *src_name)
+{
+	MS_EVENTLOG *g;
+	HANDLE h;
+	wchar_t keyname[MAX_PATH];
+	char keyname_a[MAX_PATH];
+	wchar_t *exename;
+	// 引数チェック
+	if (src_name == NULL)
+	{
+		return NULL;
+	}
+
+	// レジストリにキーを書き込む
+	exename = MsGetExeFileNameW();
+	UniFormat(keyname, sizeof(keyname),
+		L"SYSTEM\\CurrentControlSet\\Services\\Eventlog\\Application\\%s",
+		src_name);
+	UniToStr(keyname_a, sizeof(keyname_a), keyname);
+
+	MsRegWriteStrExpandExW(REG_LOCAL_MACHINE, keyname_a, "EventMessageFile",
+		exename, false);
+
+	MsRegWriteIntEx(REG_LOCAL_MACHINE, keyname_a, "TypesSupported", 7, false);
+
+	h = ms->nt->RegisterEventSourceW(NULL, src_name);
+	if (h == NULL)
+	{
+		return NULL;
+	}
+
+	g = ZeroMalloc(sizeof(MS_EVENTLOG));
+
+	g->hEventLog = h;
+
+	return (void *)g;
+}
+
+// クリップボードを空にする
+void MsDeleteClipboard()
+{
+	OpenClipboard(NULL);
+
+	EmptyClipboard();
+
+	CloseClipboard();
+}
+
+// クリップボード所有者のプロセス ID を取得する
+UINT MsGetClipboardOwnerProcessId()
+{
+	HWND hWnd = GetClipboardOwner();
+	DWORD pid = 0;
+
+	if (hWnd == NULL)
+	{
+		return 0;
+	}
+
+	GetWindowThreadProcessId(hWnd, &pid);
+
+	return pid;
+}
+
+// MMCSS の再起動
+// 注意: この実装は完璧ではない。
+void MsRestartMMCSS()
+{
+	MsStopService("CTAudSvcService");
+	MsStopService("audiosrv");
+	MsStopService("MMCSS");
+	MsStartService("MMCSS");
+	MsStartService("audiosrv");
+	MsStartService("CTAudSvcService");
+}
+
+// MMCSS によるネットワークスロットリングを有効 / 無効にする
+void MsSetMMCSSNetworkThrottlingEnable(bool enable)
+{
+	UINT value;
+	if (MsIsVista() == false)
+	{
+		return;
+	}
+
+	if (enable)
+	{
+		value = 0x0000000a;
+	}
+	else
+	{
+		value = 0xffffffff;
+	}
+
+	MsRegWriteIntEx2(REG_LOCAL_MACHINE, MMCSS_PROFILE_KEYNAME, "NetworkThrottlingIndex",
+		value,
+		false, true);
+
+	MsRestartMMCSS();
+}
+
+// MMCSS によるネットワークスロットリングが有効になっているかどうか調査
+bool MsIsMMCSSNetworkThrottlingEnabled()
+{
+	UINT value;
+	if (MsIsVista() == false)
+	{
+		return false;
+	}
+
+	if (MsRegIsKeyEx2(REG_LOCAL_MACHINE, MMCSS_PROFILE_KEYNAME, false, true) == false)
+	{
+		return false;
+	}
+
+	value = MsRegReadIntEx2(REG_LOCAL_MACHINE, MMCSS_PROFILE_KEYNAME,
+		"NetworkThrottlingIndex", false, true);
+
+	if (value == 0)
+	{
+		return false;
+	}
+
+	if (value == 0x0000000a)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// サブキーをすべて削除する
+void MsRegDeleteSubkeys(UINT root, char *keyname, bool force32bit, bool force64bit)
+{
+	TOKEN_LIST *t;
+	UINT i;
+	// 引数チェック
+	if (keyname == NULL)
+	{
+		return;
+	}
+
+	t = MsRegEnumKeyEx2(root, keyname, force32bit, force64bit);
+	if (t == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		char tmp[MAX_PATH];
+
+		Format(tmp, sizeof(tmp), "%s\\%s", keyname, t->Token[i]);
+
+		MsRegDeleteKeyEx2(root, tmp, force32bit, force64bit);
+	}
+
+	FreeToken(t);
+}
+
+// バッファのデータをレジストリのサブキーに変換する
+void MsBufToRegSubkeys(UINT root, char *keyname, BUF *b, bool overwrite, bool force32bit, bool force64bit)
+{
+	UINT i;
+	UINT a;
+	UINT num_keys;
+	// 引数チェック
+	if (keyname == NULL || b == NULL)
+	{
+		return;
+	}
+
+	SeekBuf(b, 0, 0);
+
+	num_keys = ReadBufInt(b);
+
+	for (i = 0;i < num_keys;i++)
+	{
+		char subkeyname[MAX_PATH];
+		char fullkeyname[MAX_PATH];
+		UINT j;
+		UINT num_values;
+
+		Zero(subkeyname, sizeof(subkeyname));
+		ReadBufStr(b, subkeyname, sizeof(subkeyname));
+
+		Format(fullkeyname, sizeof(fullkeyname), "%s\\%s", keyname, subkeyname);
+
+		num_values = ReadBufInt(b);
+
+		for (j = 0;j < num_values;j++)
+		{
+			char valuename[MAX_PATH];
+			char data[MAX_SIZE];
+
+			Zero(valuename, sizeof(valuename));
+			ReadBufStr(b, valuename, sizeof(valuename));
+
+			a = ReadBufInt(b);
+
+			if (a == 0)
+			{
+				Zero(data, sizeof(data));
+				ReadBufStr(b, data, sizeof(data));
+
+				if (overwrite || MsRegIsValueEx2(root, fullkeyname, valuename, force32bit, force64bit) == false)
+				{
+					MsRegWriteStrEx2(root, fullkeyname, valuename, data, force32bit, force64bit);
+				}
+			}
+			else
+			{
+				if (overwrite || MsRegIsValueEx2(root, fullkeyname, valuename, force32bit, force64bit) == false)
+				{
+					MsRegWriteIntEx2(root, fullkeyname, valuename, ReadBufInt(b), force32bit, force64bit);
+				}
+			}
+		}
+	}
+}
+
+// レジストリのサブキーのデータをバッファに変換する
+BUF *MsRegSubkeysToBuf(UINT root, char *keyname, bool force32bit, bool force64bit)
+{
+	TOKEN_LIST *t;
+	UINT i;
+	BUF *b;
+	// 引数チェック
+	if (keyname == NULL)
+	{
+		return NULL;
+	}
+
+	t = MsRegEnumKeyEx2(root, keyname, force32bit, force64bit);
+
+	if (t == NULL)
+	{
+		return NULL;
+	}
+
+	b = NewBuf();
+
+	WriteBufInt(b, t->NumTokens);
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		char *name = t->Token[i];
+		char tmp[MAX_PATH];
+		TOKEN_LIST *v;
+
+		Format(tmp, sizeof(tmp), "%s\\%s", keyname, name);
+
+		WriteBufStr(b, name);
+
+		v = MsRegEnumValueEx2(root, tmp, force32bit, force64bit);
+		if (v == NULL)
+		{
+			WriteBufInt(b, 0);
+		}
+		else
+		{
+			UINT j;
+
+			WriteBufInt(b, v->NumTokens);
+
+			for (j = 0;j < v->NumTokens;j++)
+			{
+				char *valuename = v->Token[j];
+				char *str;
+
+				WriteBufStr(b, valuename);
+
+				str = MsRegReadStrEx2(root, tmp, valuename, force32bit, force64bit);
+				if (str != NULL)
+				{
+					WriteBufInt(b, 0);
+					WriteBufStr(b, str);
+					Free(str);
+				}
+				else
+				{
+					WriteBufInt(b, 1);
+					WriteBufInt(b, MsRegReadIntEx2(root, tmp, valuename, force32bit, force64bit));
+				}
+			}
+
+			FreeToken(v);
+		}
+	}
+
+	FreeToken(t);
+
+	return b;
+}
+
+// 指定した EXE ファイル名のプロセスが存在しているかどうかチェック
+bool MsIsProcessExists(char *exename)
+{
+	LIST *o;
+	bool ret = false;
+	UINT i;
+	// 引数チェック
+	if (exename == NULL)
+	{
+		return false;
+	}
+
+	o = MsGetProcessList();
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		MS_PROCESS *proc = LIST_DATA(o, i);
+		char exe[MAX_PATH];
+
+		GetFileNameFromFilePath(exe, sizeof(exe), proc->ExeFilename);
+
+		if (StrCmpi(exename, exe) == 0)
+		{
+			ret = true;
+			break;
+		}
+	}
+
+	MsFreeProcessList(o);
+
+	return ret;
+}
+bool MsIsProcessExistsW(wchar_t *exename)
+{
+	LIST *o;
+	bool ret = false;
+	UINT i;
+	// 引数チェック
+	if (exename == NULL)
+	{
+		return false;
+	}
+
+	o = MsGetProcessList();
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		MS_PROCESS *proc = LIST_DATA(o, i);
+		wchar_t exe[MAX_PATH];
+
+		GetFileNameFromFilePathW(exe, sizeof(exe), proc->ExeFilenameW);
+
+		if (UniStrCmpi(exename, exe) == 0)
+		{
+			ret = true;
+			break;
+		}
+	}
+
+	MsFreeProcessList(o);
+
+	return ret;
+}
+
+typedef struct _ASTAT_
+{
+	ADAPTER_STATUS adapt;
+	NAME_BUFFER    NameBuff[30];
+} ASTAT, *PASTAT;
+
+// 高精度カウンタの値から精密な時間を取得する
+double MsGetHiResTimeSpan(UINT64 diff)
+{
+	LARGE_INTEGER t;
+	UINT64 freq;
+
+	if (QueryPerformanceFrequency(&t) == false)
+	{
+		freq = 1000ULL;
+	}
+	else
+	{
+		Copy(&freq, &t, sizeof(UINT64));
+	}
+
+	return (double)diff / (double)freq;
+}
+UINT64 MsGetHiResTimeSpanUSec(UINT64 diff)
+{
+	LARGE_INTEGER t;
+	UINT64 freq;
+
+	if (QueryPerformanceFrequency(&t) == false)
+	{
+		freq = 1000ULL;
+	}
+	else
+	{
+		Copy(&freq, &t, sizeof(UINT64));
+	}
+
+	return (UINT64)(diff) * 1000ULL * 1000ULL / (UINT64)freq;
+}
+
+// 高精度カウンタを取得する
+UINT64 MsGetHiResCounter()
+{
+	LARGE_INTEGER t;
+	UINT64 ret;
+
+	if (QueryPerformanceCounter(&t) == false)
+	{
+		return Tick64();
+	}
+
+	Copy(&ret, &t, sizeof(UINT64));
+
+	return ret;
+}
+
+// ようこそ画面を使用しているかどうか
+bool MsIsUseWelcomeLogin()
+{
+	UINT os_type;
+	if (MsIsNt() == false)
+	{
+		return false;
+	}
+
+	os_type = GetOsInfo()->OsType;
+
+	if (OS_IS_WINDOWS_NT(os_type))
+	{
+		if (GET_KETA(os_type, 100) == 3)
+		{
+			if (MsRegReadIntEx2(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
+				"LogonType", false, true) == 0)
+			{
+				return false;
+			}
+			else
+			{
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+// コンピュータの物理的な MAC アドレスを 1 つ取得する
+bool MsGetPhysicalMacAddress(void *address)
+{
+	// 引数チェック
+	if (address == NULL)
+	{
+		return false;
+	}
+
+	if (MsGetPhysicalMacAddressFromApi(address))
+	{
+		return true;
+	}
+
+	if (MsGetPhysicalMacAddressFromNetbios(address))
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// 物理的な MAC アドレスを取得する (API から)
+bool MsGetPhysicalMacAddressFromApi(void *address)
+{
+	MS_ADAPTER_LIST *o;
+	UINT i;
+	bool ret = false;
+	// 引数チェック
+	if (address == NULL)
+	{
+		return false;
+	}
+
+	Zero(address, 6);
+
+	o = MsCreateAdapterList();
+
+	for (i = 0;i < o->Num;i++)
+	{
+		MS_ADAPTER *a = o->Adapters[i];
+
+		if (a->AddressSize == 6 && a->Mtu == 1500)
+		{
+			bool b = false;
+			switch (a->Type)
+			{
+			case MIB_IF_TYPE_OTHER:
+			case MIB_IF_TYPE_ETHERNET:
+				b = true;
+				break;
+
+			case MIB_IF_TYPE_TOKENRING:
+			case MIB_IF_TYPE_FDDI:
+			case MIB_IF_TYPE_PPP:
+			case MIB_IF_TYPE_LOOPBACK:
+			case MIB_IF_TYPE_SLIP:
+				b = false;
+				break;
+
+			default:
+				b = true;
+				break;
+			}
+
+			if (b)
+			{
+				if (SearchStrEx(a->Title, "WAN", 0, false) == INFINITE)
+				{
+					if (a->Status == MIB_IF_OPER_STATUS_CONNECTED || a->Status == MIB_IF_OPER_STATUS_OPERATIONAL)
+					{
+						if (a->AddressSize == 6)
+						{
+							if (IsZero(a->Address, 6) == false)
+							{
+								if (Cmp(address, a->Address, 6) <= 0)
+								{
+									Copy(address, a->Address, 6);
+									ret = true;
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	MsFreeAdapterList(o);
+
+	return ret;
+}
+
+// 物理的な MAC アドレスを取得する (NetBIOS から)
+bool MsGetPhysicalMacAddressFromNetbios(void *address)
+{
+	NCB ncb;
+	UCHAR ret;
+	LANA_ENUM lenum;
+	UINT i;
+	ASTAT adapter;
+	bool b = false;
+	// 引数チェック
+	if (address == NULL)
+	{
+		return false;
+	}
+
+	Zero(&ncb, sizeof(ncb));
+	Zero(&lenum, sizeof(lenum));
+
+	ncb.ncb_command = NCBENUM;
+	ncb.ncb_buffer = (UCHAR *)&lenum;
+	ncb.ncb_length = sizeof(lenum);
+	ret = Netbios(&ncb);
+
+	Zero(address, 6);
+
+	for (i = 0;i < lenum.length;i++)
+	{
+		Zero(&ncb, sizeof(ncb));
+		ncb.ncb_command = NCBRESET;
+		ncb.ncb_lana_num = lenum.lana[i];
+
+		ret = Netbios(&ncb);
+
+		Zero(&ncb, sizeof(ncb));
+		ncb.ncb_command = NCBASTAT;
+		ncb.ncb_lana_num = lenum.lana[i];
+
+		StrCpy(ncb.ncb_callname, sizeof(ncb.ncb_callname), "*               ");
+		Zero(&adapter, sizeof(adapter));
+		ncb.ncb_buffer = (char *)&adapter;
+		ncb.ncb_length = sizeof(adapter);
+
+		ret = Netbios(&ncb);
+
+		if (ret == 0)
+		{
+			if (Cmp(address, adapter.adapt.adapter_address, 6) <= 0)
+			{
+				Copy(address, adapter.adapt.adapter_address, 6);
+				b = true;
+			}
+		}
+	}
+
+	return b;
+}
+
+// システム全体のアップデート通知
+void MsUpdateSystem()
+{
+	static DWORD dw = 0;
+
+	SendMessageTimeoutA(HWND_BROADCAST, WM_WININICHANGE, 0, 0, SMTO_NORMAL, 1, (PDWORD_PTR)&dw);
+}
+
+// 指定されたパスがローカルドライブかどうか取得する
+bool MsIsLocalDrive(char *name)
+{
+	char tmp[MAX_PATH];
+	UINT ret;
+
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	Zero(tmp, sizeof(tmp));
+	InnerFilePath(tmp, sizeof(tmp), name);
+
+	if (StartWith(tmp, "\\\\"))
+	{
+		// ネットワークディレクトリ
+		return false;
+	}
+
+	if (tmp[1] != ':' || tmp[2] != '\\')
+	{
+		// ドライブ名でない
+		return false;
+	}
+
+	tmp[3] = 0;
+
+	ret = GetDriveType(tmp);
+
+	if (ret == DRIVE_REMOTE || ret == DRIVE_CDROM || ret == DRIVE_RAMDISK)
+	{
+		return false;
+	}
+
+	return true;
+}
+bool MsIsLocalDriveW(wchar_t *name)
+{
+	char name_a[MAX_PATH];
+
+	UniToStr(name_a, sizeof(name_a), name);
+
+	return MsIsLocalDrive(name_a);
+}
+
+// 指定されたファイルがロックされているかどうか取得する
+bool MsIsFileLocked(char *name)
+{
+	HANDLE h;
+	char tmp[MAX_PATH];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	InnerFilePath(tmp, sizeof(tmp), name);
+
+	h = CreateFile(tmp, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		return true;
+	}
+
+	CloseHandle(h);
+
+	return false;
+}
+bool MsIsFileLockedW(wchar_t *name)
+{
+	HANDLE h;
+	wchar_t tmp[MAX_PATH];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char name_a[MAX_SIZE];
+
+		UniToStr(name_a, sizeof(name_a), name);
+
+		return MsIsFileLocked(name_a);
+	}
+
+	InnerFilePathW(tmp, sizeof(tmp), name);
+
+	h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, NULL);
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		return true;
+	}
+
+	CloseHandle(h);
+
+	return false;
+}
+
+// プロセスの終了を待機
+UINT MsWaitProcessExit(void *process_handle)
+{
+	HANDLE h = (HANDLE)process_handle;
+	UINT ret = 1;
+
+	if (h == NULL)
+	{
+		return 1;
+	}
+
+	while (true)
+	{
+		WaitForSingleObject(h, INFINITE);
+
+		ret = 1;
+		if (GetExitCodeProcess(h, &ret) == false)
+		{
+			break;
+		}
+
+		if (ret != STILL_ACTIVE)
+		{
+			break;
+		}
+	}
+
+	CloseHandle(h);
+
+	return ret;
+}
+
+// ファイルの実行 (プロセスハンドル取得)
+bool MsExecuteEx(char *exe, char *arg, void **process_handle)
+{
+	SHELLEXECUTEINFO info;
+	HANDLE h;
+	// 引数チェック
+	if (exe == NULL || process_handle == NULL)
+	{
+		return false;
+	}
+
+	Zero(&info, sizeof(info));
+	info.cbSize = sizeof(info);
+	info.lpVerb = "open";
+	info.lpFile = exe;
+	info.fMask = SEE_MASK_NOCLOSEPROCESS;
+	info.lpParameters = arg;
+	info.nShow = SW_SHOWNORMAL;
+	if (ShellExecuteEx(&info) == false)
+	{
+		return false;
+	}
+
+	h = info.hProcess;
+
+	*process_handle = (void *)h;
+
+	return true;
+}
+bool MsExecuteExW(wchar_t *exe, wchar_t *arg, void **process_handle)
+{
+	SHELLEXECUTEINFOW info;
+	HANDLE h;
+	// 引数チェック
+	if (exe == NULL || process_handle == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char exe_a[MAX_SIZE];
+		char arg_a[MAX_SIZE];
+
+		UniToStr(exe_a, sizeof(exe_a), exe);
+		UniToStr(arg_a, sizeof(arg_a), arg);
+
+		return MsExecuteEx(exe_a, arg_a, process_handle);
+	}
+
+	Zero(&info, sizeof(info));
+	info.cbSize = sizeof(info);
+	info.lpVerb = L"open";
+	info.lpFile = exe;
+	info.fMask = SEE_MASK_NOCLOSEPROCESS;
+	info.lpParameters = arg;
+	info.nShow = SW_SHOWNORMAL;
+	if (ShellExecuteExW(&info) == false)
+	{
+		return false;
+	}
+
+	h = info.hProcess;
+
+	*process_handle = (void *)h;
+
+	return true;
+}
+
+// ファイルの実行
+bool MsExecute(char *exe, char *arg)
+{
+	DWORD d;
+	// 引数チェック
+	if (exe == NULL)
+	{
+		return false;
+	}
+
+	d = (DWORD)ShellExecuteA(NULL, "open", exe, arg, MsGetExeDirName(), SW_SHOWNORMAL);
+
+	if (d > 32)
+	{
+		return true;
+	}
+
+	return false;
+}
+bool MsExecuteW(wchar_t *exe, wchar_t *arg)
+{
+	DWORD d;
+	// 引数チェック
+	if (exe == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char exe_a[MAX_SIZE];
+		char arg_a[MAX_SIZE];
+
+		UniToStr(exe_a, sizeof(exe_a), exe);
+		UniToStr(arg_a, sizeof(arg_a), arg);
+
+		return MsExecute(exe_a, arg_a);
+	}
+
+	d = (DWORD)ShellExecuteW(NULL, L"open", exe, arg, MsGetExeDirNameW(), SW_SHOWNORMAL);
+
+	if (d > 32)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// ディレクトリの再帰作成
+void MsUniMakeDirEx(wchar_t *name)
+{
+	UINT wp;
+	wchar_t *tmp;
+	UINT i, len;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	tmp = ZeroMalloc(UniStrSize(name) * 2);
+	wp = 0;
+	len = UniStrLen(name);
+	for (i = 0;i < len;i++)
+	{
+		wchar_t c = name[i];
+
+		if (c == '\\')
+		{
+			if (UniStrCmpi(tmp, L"\\\\") != 0 && UniStrCmpi(tmp, L"\\") != 0)
+			{
+				MsUniMakeDir(tmp);
+			}
+		}
+
+		tmp[wp++] = c;
+	}
+
+	Free(tmp);
+
+	MsUniMakeDir(name);
+}
+void MsMakeDirEx(char *name)
+{
+	wchar_t *name_w = CopyStrToUni(name);
+
+	MsUniMakeDirEx(name_w);
+
+	Free(name_w);
+}
+
+// ディレクトリの作成
+bool MsUniMakeDir(wchar_t *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		char *s = CopyUniToStr(name);
+		bool ret = MsMakeDir(s);
+		Free(s);
+		return ret;
+	}
+
+	return CreateDirectoryW(name, NULL);
+}
+bool MsMakeDir(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	return CreateDirectoryA(name, NULL);
+}
+
+// ディレクトリの削除
+bool MsUniDirectoryDelete(wchar_t *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		char *s = CopyUniToStr(name);
+		bool ret = MsDirectoryDelete(s);
+		Free(s);
+		return ret;
+	}
+
+	return RemoveDirectoryW(name);
+}
+bool MsDirectoryDelete(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	return RemoveDirectoryA(name);
+}
+
+// ファイルの削除
+bool MsUniFileDelete(wchar_t *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		bool ret;
+		char *s = CopyUniToStr(name);
+		ret = MsFileDelete(s);
+		Free(s);
+		return ret;
+	}
+
+	return DeleteFileW(name);
+}
+bool MsFileDelete(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	return DeleteFileA(name);
+}
+
+// 指定したファイル名がディレクトリかどうか取得する
+bool MsUniIsDirectory(wchar_t *name)
+{
+	DWORD ret;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		char *s = CopyUniToStr(name);
+		ret = MsIsDirectory(s);
+		Free(s);
+
+		return ret;
+	}
+
+	ret = GetFileAttributesW(name);
+	if (ret == 0xffffffff)
+	{
+		return false;
+	}
+
+	if (ret & FILE_ATTRIBUTE_DIRECTORY)
+	{
+		return true;
+	}
+
+	return false;
+}
+bool MsIsDirectoryW(wchar_t *name)
+{
+	return MsUniIsDirectory(name);
+}
+bool MsIsDirectory(char *name)
+{
+	DWORD ret;
+	char tmp[MAX_PATH];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	InnerFilePath(tmp, sizeof(tmp), name);
+
+	ret = GetFileAttributesA(tmp);
+	if (ret == 0xffffffff)
+	{
+		return false;
+	}
+
+	if (ret & FILE_ATTRIBUTE_DIRECTORY)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// MSI ファイルから Cabinet を取り出す
+bool MsExtractCabFromMsi(char *msi, char *cab)
+{
+	wchar_t msi_w[MAX_PATH];
+	wchar_t cab_w[MAX_PATH];
+
+	StrToUni(msi_w, sizeof(msi_w), msi);
+	StrToUni(cab_w, sizeof(cab_w), cab);
+
+	return MsExtractCabFromMsiW(msi_w, cab_w);
+}
+bool MsExtractCabFromMsiW(wchar_t *msi, wchar_t *cab)
+{
+	BUF *b;
+	bool ret = false;
+	UINT i;
+	char sign[] = {'M', 'S', 'C', 'F', 0, 0, 0, 0,};
+	void *pointer = NULL;
+	UINT current_pos = 0;
+	UINT sign_size;
+	// 引数チェック
+	if (msi == NULL || cab == NULL)
+	{
+		return false;
+	}
+
+	// MSI を読み込む
+	b = ReadDumpW(msi);
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	if (b->Size < 128)
+	{
+		FreeBuf(b);
+		return false;
+	}
+
+	sign_size = sizeof(sign);
+
+	// "MSCF" を検索する
+	for (i = 0;i < (b->Size - sign_size);i++)
+	{
+		char *p = ((UCHAR *)b->Buf) + i;
+
+		if (Cmp(p, sign, sign_size) == 0)
+		{
+			pointer = p;
+			current_pos = i;
+		}
+	}
+
+	if (pointer != NULL)
+	{
+		UINT size = b->Size - current_pos;
+		BUF *b2 = NewBuf();
+
+		WriteBuf(b2, pointer, size);
+
+		ret = DumpBufW(b2, cab);
+
+		FreeBuf(b2);
+
+	}
+
+	FreeBuf(b);
+
+	return ret;
+}
+
+// Cabinet ファイルからファイルを取り出す
+bool MsExtractCab(char *cab_name, char *dest_dir_name)
+{
+	wchar_t cab_name_w[MAX_SIZE];
+	wchar_t dest_dir_name_w[MAX_SIZE];
+
+	StrToUni(cab_name_w, sizeof(cab_name_w), cab_name);
+	StrToUni(dest_dir_name_w, sizeof(dest_dir_name_w), dest_dir_name);
+
+	return MsExtractCabW(cab_name_w, dest_dir_name_w);
+}
+bool MsExtractCabW(wchar_t *cab_name, wchar_t *dest_dir_name)
+{
+	wchar_t cabarc[MAX_PATH];
+	wchar_t arg[MAX_PATH * 2];
+	wchar_t tmp[MAX_PATH];
+
+	// 引数チェック
+	if (cab_name == NULL || dest_dir_name == NULL)
+	{
+		return false;
+	}
+
+	if (MsGetCabarcExeFilenameW(cabarc, sizeof(cabarc)) == false)
+	{
+		return false;
+	}
+
+	UniStrCpy(tmp, sizeof(tmp), dest_dir_name);
+	if (UniEndWith(tmp, L"\\"))
+	{
+		tmp[UniStrLen(tmp) - 1] = 0;
+	}
+
+	UniFormat(arg, sizeof(arg),
+		L"-o X \"%s\" * \"%s\"\\",
+		cab_name,
+		tmp);
+
+	MakeDirW(dest_dir_name);
+
+	if (RunW(cabarc, arg, true, true) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// cabarc.exe の展開
+bool MsGetCabarcExeFilename(char *name, UINT size)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	ConbinePath(name, size, MsGetMyTempDir(), "cabarc.exe");
+
+	if (IsFileExists(name))
+	{
+		return true;
+	}
+
+	if (FileCopy("|cabarc.exe", name) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+bool MsGetCabarcExeFilenameW(wchar_t *name, UINT size)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	ConbinePathW(name, size, MsGetMyTempDirW(), L"cabarc.exe");
+
+	if (IsFileExistsW(name))
+	{
+		return true;
+	}
+
+	if (FileCopyW(L"|cabarc.exe", name) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// EXE ファイルから Cabinet ファイルを取り出す
+bool MsExtractCabinetFileFromExe(char *exe, char *cab)
+{
+	BUF *b;
+	// 引数チェック
+	if (exe == NULL || cab == NULL)
+	{
+		return false;
+	}
+
+	b = MsExtractResourceFromExe(exe, RT_RCDATA, "CABINET");
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	if (DumpBuf(b, cab) == false)
+	{
+		FreeBuf(b);
+
+		return false;
+	}
+
+	FreeBuf(b);
+
+	return true;
+}
+bool MsExtractCabinetFileFromExeW(wchar_t *exe, wchar_t *cab)
+{
+	BUF *b;
+	// 引数チェック
+	if (exe == NULL || cab == NULL)
+	{
+		return false;
+	}
+
+	b = MsExtractResourceFromExeW(exe, RT_RCDATA, "CABINET");
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	if (DumpBufW(b, cab) == false)
+	{
+		FreeBuf(b);
+
+		return false;
+	}
+
+	FreeBuf(b);
+
+	return true;
+}
+
+// EXE ファイルからリソースを取り出す
+BUF *MsExtractResourceFromExe(char *exe, char *type, char *name)
+{
+	HINSTANCE h;
+	HRSRC hr;
+	HGLOBAL hg;
+	UINT size;
+	void *data;
+	BUF *buf;
+	// 引数チェック
+	if (exe == NULL || type == NULL || name == NULL)
+	{
+		return NULL;
+	}
+
+	h = LoadLibraryExA(exe, NULL, LOAD_LIBRARY_AS_DATAFILE);
+	if (h == NULL)
+	{
+		return NULL;
+	}
+
+	hr = FindResourceA(h, name, type);
+	if (hr == NULL)
+	{
+		FreeLibrary(h);
+		return NULL;
+	}
+
+	hg = LoadResource(h, hr);
+	if (hg == NULL)
+	{
+		FreeLibrary(h);
+		return NULL;
+	}
+
+	size = SizeofResource(h, hr);
+	data = (void *)LockResource(hg);
+
+	buf = NewBuf();
+	WriteBuf(buf, data, size);
+
+	FreeResource(hg);
+	FreeLibrary(h);
+
+	SeekBuf(buf, 0, 0);
+
+	return buf;
+}
+BUF *MsExtractResourceFromExeW(wchar_t *exe, char *type, char *name)
+{
+	HINSTANCE h;
+	HRSRC hr;
+	HGLOBAL hg;
+	UINT size;
+	void *data;
+	BUF *buf;
+	// 引数チェック
+	if (exe == NULL || type == NULL || name == NULL)
+	{
+		return NULL;
+	}
+
+	if (IsNt() == false)
+	{
+		char exe_a[MAX_PATH];
+
+		UniToStr(exe_a, sizeof(exe_a), exe);
+
+		return MsExtractResourceFromExe(exe_a, type, name);
+	}
+
+	h = LoadLibraryExW(exe, NULL, LOAD_LIBRARY_AS_DATAFILE);
+	if (h == NULL)
+	{
+		return NULL;
+	}
+
+	hr = FindResource(h, name, type);
+	if (hr == NULL)
+	{
+		FreeLibrary(h);
+		return NULL;
+	}
+
+	hg = LoadResource(h, hr);
+	if (hg == NULL)
+	{
+		FreeLibrary(h);
+		return NULL;
+	}
+
+	size = SizeofResource(h, hr);
+	data = (void *)LockResource(hg);
+
+	buf = NewBuf();
+	WriteBuf(buf, data, size);
+
+	FreeResource(hg);
+	FreeLibrary(h);
+
+	SeekBuf(buf, 0, 0);
+
+	return buf;
+}
+
+// ファイルのバージョン情報を取得する
+bool MsGetFileVersion(char *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4)
+{
+	void *data;
+	UINT size;
+	DWORD h;
+	bool ret = false;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	h = 0;
+	size = GetFileVersionInfoSize(name, &h);
+	if (size == 0)
+	{
+		return false;
+	}
+
+	data = ZeroMalloc(size);
+
+	if (GetFileVersionInfoA(name, 0, size, data))
+	{
+		VS_FIXEDFILEINFO *info = NULL;
+		UINT info_size = 0;
+		if (VerQueryValueA(data, "\\", &info, &info_size))
+		{
+			if (v1 != NULL)
+			{
+				*v1 = HIWORD(info->dwFileVersionMS);
+			}
+
+			if (v2 != NULL)
+			{
+				*v2 = LOWORD(info->dwFileVersionMS);
+			}
+
+			if (v3 != NULL)
+			{
+				*v3 = HIWORD(info->dwFileVersionLS);
+			}
+
+			if (v4 != NULL)
+			{
+				*v4 = LOWORD(info->dwFileVersionLS);
+			}
+
+			ret = true;
+		}
+	}
+
+	Free(data);
+
+	return ret;
+}
+bool MsGetFileVersionW(wchar_t *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4)
+{
+	void *data;
+	UINT size;
+	DWORD h;
+	bool ret = false;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char name_a[MAX_PATH];
+
+		UniToStr(name_a, sizeof(name_a), name);
+
+		return MsGetFileVersion(name_a, v1, v2, v3, v4);
+	}
+
+	h = 0;
+	size = GetFileVersionInfoSizeW(name, &h);
+	if (size == 0)
+	{
+		return false;
+	}
+
+	data = ZeroMalloc(size);
+
+	if (GetFileVersionInfoW(name, 0, size, data))
+	{
+		VS_FIXEDFILEINFO *info = NULL;
+		UINT info_size = 0;
+		if (VerQueryValue(data, "\\", &info, &info_size))
+		{
+			if (v1 != NULL)
+			{
+				*v1 = HIWORD(info->dwFileVersionMS);
+			}
+
+			if (v2 != NULL)
+			{
+				*v2 = LOWORD(info->dwFileVersionMS);
+			}
+
+			if (v3 != NULL)
+			{
+				*v3 = HIWORD(info->dwFileVersionLS);
+			}
+
+			if (v4 != NULL)
+			{
+				*v4 = LOWORD(info->dwFileVersionLS);
+			}
+
+			ret = true;
+		}
+	}
+
+	Free(data);
+
+	return ret;
+}
+
+// ファイルを隠しファイルにする
+void MsSetFileToHidden(char *name)
+{
+	char tmp[MAX_PATH];
+	DWORD d;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	NormalizePath(tmp, sizeof(tmp), name);
+
+	d = GetFileAttributesA(tmp);
+	if (d != INVALID_FILE_ATTRIBUTES)
+	{
+		d |= FILE_ATTRIBUTE_HIDDEN;
+
+		SetFileAttributesA(tmp, d);
+	}
+}
+void MsSetFileToHiddenW(wchar_t *name)
+{
+	wchar_t tmp[MAX_PATH];
+	DWORD d;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	if (IsNt() == false)
+	{
+		char name_a[MAX_SIZE];
+
+		UniToStr(name_a, sizeof(name_a), name);
+
+		MsSetFileToHidden(name_a);
+
+		return;
+	}
+
+	NormalizePathW(tmp, sizeof(tmp), name);
+
+	d = GetFileAttributesW(tmp);
+	if (d != INVALID_FILE_ATTRIBUTES)
+	{
+		d |= FILE_ATTRIBUTE_HIDDEN;
+
+		SetFileAttributesW(tmp, d);
+	}
+}
+
+// スリープ防止用スレッド
+void MsNoSleepThread(THREAD *thread, void *param)
+{
+	MS_NOSLEEP *e;
+	EXECUTION_STATE (WINAPI *_SetThreadExecutionState)(EXECUTION_STATE);
+	HINSTANCE hKernel32;
+	// 引数チェック
+	if (thread == NULL || param == NULL)
+	{
+		return;
+	}
+
+	hKernel32 = LoadLibrary("kernel32.dll");
+
+	_SetThreadExecutionState =
+		(EXECUTION_STATE (__stdcall *)(EXECUTION_STATE))
+		GetProcAddress(hKernel32, "SetThreadExecutionState");
+
+	e = (MS_NOSLEEP *)param;
+
+	while (e->Halt == false)
+	{
+		DWORD flag = ES_SYSTEM_REQUIRED;
+
+		if (e->NoScreenSaver)
+		{
+			flag |= ES_DISPLAY_REQUIRED;
+		}
+
+		if (_SetThreadExecutionState != NULL)
+		{
+			_SetThreadExecutionState(flag);
+		}
+
+		Wait(e->HaltEvent, 30 * 1000);
+	}
+
+	FreeLibrary(hKernel32);
+}
+
+// スリープ防止用スレッド (Windows Vista 用)
+void MsNoSleepThreadVista(THREAD *thread, void *param)
+{
+	MS_NOSLEEP *e;
+	char *key = "Control Panel\\Desktop";
+	UINT64 last_set_flag = 0;
+	UINT last_c_x = INFINITE, last_c_y = INFINITE;
+	UINT64 last_mouse_move_time = 0;
+	EXECUTION_STATE (WINAPI *_SetThreadExecutionState)(EXECUTION_STATE);
+	HINSTANCE hKernel32;
+	// 引数チェック
+	if (thread == NULL || param == NULL)
+	{
+		return;
+	}
+
+	hKernel32 = LoadLibrary("kernel32.dll");
+
+	_SetThreadExecutionState =
+		(EXECUTION_STATE (__stdcall *)(EXECUTION_STATE))
+		GetProcAddress(hKernel32, "SetThreadExecutionState");
+
+	e = (MS_NOSLEEP *)param;
+
+	while (e->Halt == false)
+	{
+		DWORD flag = ES_SYSTEM_REQUIRED;
+		UINT64 now = Tick64();
+		POINT p;
+		bool mouse_move = false;
+
+		Zero(&p, sizeof(p));
+		GetCursorPos(&p);
+
+		if (p.x != last_c_x || p.y != last_c_y)
+		{
+			if (last_c_x != INFINITE && last_c_y != INFINITE)
+			{
+				mouse_move = true;
+			}
+
+			last_c_x = p.x;
+			last_c_y = p.y;
+		}
+
+		if (mouse_move)
+		{
+			last_mouse_move_time = now;
+		}
+
+		if (last_mouse_move_time == 0 || (now > (last_mouse_move_time + 50000ULL)))
+		{
+			wchar_t *active;
+			wchar_t *exe;
+			// マウスが 50 秒以上動かない場合はスクリーンセーバーの設定を削除する
+
+			active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive");
+			exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE");
+
+			if (UniToInt(active) != 0 && UniIsEmptyStr(exe) == false)
+			{
+				// スクリーンセーバーが設定されている
+				UniStrCpy(e->ScreenSaveActive, sizeof(e->ScreenSaveActive), active);
+				UniStrCpy(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE), exe);
+
+				MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", L"0");
+				MsRegDeleteValue(REG_CURRENT_USER, key, "SCRNSAVE.EXE");
+
+				Debug("Push SS Settings.\n");
+			}
+
+			Free(active);
+			Free(exe);
+
+			last_mouse_move_time = now;
+		}
+		else
+		{
+			if (mouse_move)
+			{
+				if (UniIsEmptyStr(e->ScreenSaveActive) == false && UniIsEmptyStr(e->SCRNSAVE_EXE) == false)
+				{
+					// マウスが動いた場合でスクリーンセーバーが設定されていない場合は
+					// スクリーンセーバーの設定を復元する
+					wchar_t *active;
+					wchar_t *exe;
+
+					active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive");
+					exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE");
+
+					if (UniToInt(active) != 0 && UniIsEmptyStr(exe) == false)
+					{
+					}
+					else
+					{
+						MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", e->ScreenSaveActive);
+						MsRegWriteStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE", e->SCRNSAVE_EXE);
+
+						Zero(e->ScreenSaveActive, sizeof(e->ScreenSaveActive));
+						Zero(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE));
+
+						Debug("Pop SS Settings.\n");
+					}
+
+					Free(active);
+					Free(exe);
+				}
+			}
+		}
+
+		if (last_set_flag == 0 || (now > (last_set_flag + 50000ULL)))
+		{
+			// フラグセット (50 秒間隔)
+			last_set_flag = now;
+
+			if (_SetThreadExecutionState != NULL)
+			{
+				_SetThreadExecutionState(flag);
+			}
+		}
+
+		Wait(e->HaltEvent, 512);
+	}
+
+	if (true)
+	{
+		// スクリーンセーバーの設定を復元する
+		wchar_t *active;
+		wchar_t *exe;
+
+		if (UniIsEmptyStr(e->ScreenSaveActive) == false && UniIsEmptyStr(e->SCRNSAVE_EXE) == false)
+		{
+			active = MsRegReadStrW(REG_CURRENT_USER, key, "ScreenSaveActive");
+			exe = MsRegReadStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE");
+
+			if (UniToInt(active) != 0 && UniIsEmptyStr(exe) != 0)
+			{
+			}
+			else
+			{
+				MsRegWriteStrW(REG_CURRENT_USER, key, "ScreenSaveActive", e->ScreenSaveActive);
+				MsRegWriteStrW(REG_CURRENT_USER, key, "SCRNSAVE.EXE", e->SCRNSAVE_EXE);
+
+				Zero(e->ScreenSaveActive, sizeof(e->ScreenSaveActive));
+				Zero(e->SCRNSAVE_EXE, sizeof(e->SCRNSAVE_EXE));
+
+				Debug("Pop SS Settings.\n");
+			}
+
+			Free(active);
+			Free(exe);
+		}
+	}
+
+	FreeLibrary(hKernel32);
+}
+
+// スリープ防止の開始
+void *MsNoSleepStart(bool no_screensaver)
+{
+	MS_NOSLEEP *e;
+	bool is_vista = MsIsVista();
+	bool is_nt_4 = false;
+	UINT os_type = GetOsInfo()->OsType;
+
+	if (OS_IS_WINDOWS_NT(os_type))
+	{
+		if (GET_KETA(os_type, 100) == 1)
+		{
+			is_nt_4 = true;
+		}
+	}
+
+	e = ZeroMalloc(sizeof(MS_NOSLEEP));
+
+	e->HaltEvent = NewEvent();
+	e->NoScreenSaver = no_screensaver;
+
+	if (e->NoScreenSaver == false || (is_vista == false && is_nt_4 == false))
+	{
+		e->Thread = NewThread(MsNoSleepThread, e);
+	}
+	else
+	{
+		e->Thread = NewThread(MsNoSleepThreadVista, e);
+	}
+
+	return (void *)e;
+}
+
+// スリープ防止の停止
+void MsNoSleepEnd(void *p)
+{
+	MS_NOSLEEP *e;
+	// 引数チェック
+	if (p == NULL)
+	{
+		return;
+	}
+
+	e = (MS_NOSLEEP *)p;
+
+	e->Halt = true;
+	Set(e->HaltEvent);
+
+	WaitThread(e->Thread, INFINITE);
+	ReleaseThread(e->Thread);
+	ReleaseEvent(e->HaltEvent);
+
+	Free(e);
+}
+
+// コンピュータ名の取得
+void MsGetComputerName(char *name, UINT size)
+{
+	DWORD sz;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	sz = size;
+	GetComputerName(name, &sz);
+}
+
+// マウスカーソルの位置のハッシュ値を取得
+UINT MsGetCursorPosHash()
+{
+	POINT p;
+
+	Zero(&p, sizeof(p));
+
+	if (GetCursorPos(&p) == false)
+	{
+		return 0;
+	}
+
+	return MAKELONG((USHORT)p.x, (USHORT)p.y);
+}
+
+// 一般ユーザー権限としてのプロセスの起動
+void *MsRunAsUserEx(char *filename, char *arg, bool hide)
+{
+	void *ret = MsRunAsUserExInner(filename, arg, hide);
+
+	if (ret == NULL)
+	{
+		Debug("MsRunAsUserExInner Failed.\n");
+		ret = Win32RunEx(filename, arg, hide);
+	}
+
+	return ret;
+}
+void *MsRunAsUserExW(wchar_t *filename, wchar_t *arg, bool hide)
+{
+	void *ret = MsRunAsUserExInnerW(filename, arg, hide);
+
+	if (ret == NULL)
+	{
+		Debug("MsRunAsUserExInner Failed.\n");
+		ret = Win32RunExW(filename, arg, hide);
+	}
+
+	return ret;
+}
+void *MsRunAsUserExInner(char *filename, char *arg, bool hide)
+{
+	void *ret;
+	wchar_t *filename_w;
+	wchar_t *arg_w;
+
+	filename_w = CopyStrToUni(filename);
+	arg_w = CopyStrToUni(arg);
+
+	ret = MsRunAsUserExInnerW(filename_w, arg_w, hide);
+
+	Free(filename_w);
+	Free(arg_w);
+
+	return ret;
+}
+void *MsRunAsUserExInnerW(wchar_t *filename, wchar_t *arg, bool hide)
+{
+	STARTUPINFOW info;
+	PROCESS_INFORMATION ret;
+	wchar_t cmdline[MAX_SIZE];
+	wchar_t name[MAX_PATH];
+	HANDLE hToken;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return NULL;
+	}
+
+	if (MsIsVista() == false)
+	{
+		// Windows Vista 以外では使用できない
+		return NULL;
+	}
+
+	UniStrCpy(name, sizeof(name), filename);
+	UniTrim(name);
+
+	if (UniSearchStr(name, L"\"", 0) == INFINITE)
+	{
+		if (arg == NULL)
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"%s", name);
+		}
+		else
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"%s %s", name, arg);
+		}
+	}
+	else
+	{
+		if (arg == NULL)
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"\"%s\"", name);
+		}
+		else
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"\"%s\" %s", name, arg);
+		}
+	}
+
+	Zero(&info, sizeof(info));
+	Zero(&ret, sizeof(ret));
+	info.cb = sizeof(info);
+	info.dwFlags = STARTF_USESHOWWINDOW;
+	info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
+
+	UniTrim(cmdline);
+
+	hToken = MsCreateUserToken();
+
+	if (hToken == NULL)
+	{
+		return NULL;
+	}
+
+	if (ms->nt->CreateProcessAsUserW(hToken, NULL, cmdline, NULL, NULL, FALSE,
+		(hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
+		NULL, NULL, &info, &ret) == FALSE)
+	{
+		return NULL;
+	}
+
+	CloseHandle(hToken);
+
+	CloseHandle(ret.hThread);
+	return ret.hProcess;
+}
+
+// アカウント名から SID を取得する
+SID *MsGetSidFromAccountName(char *name)
+{
+	SID *sid;
+	UINT sid_size = 4096;
+	char *domain_name;
+	UINT domain_name_size = 4096;
+	SID_NAME_USE use = SidTypeUser;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	if (MsIsNt() == false)
+	{
+		return NULL;
+	}
+
+	sid = ZeroMalloc(sid_size);
+	domain_name = ZeroMalloc(domain_name_size);
+
+	if (ms->nt->LookupAccountNameA(NULL, name, sid, &sid_size, domain_name, &domain_name_size, &use) == false)
+	{
+		Free(sid);
+		Free(domain_name);
+		return NULL;
+	}
+
+	Free(domain_name);
+
+	return sid;
+}
+
+// SID を解放する
+void MsFreeSid(SID *sid)
+{
+	// 引数チェック
+	if (sid == NULL)
+	{
+		return;
+	}
+
+	Free(sid);
+}
+
+// 一般ユーザーのトークンを作成する
+HANDLE MsCreateUserToken()
+{
+	char *medium_sid = "S-1-16-8192";
+	char *administrators_sid = "S-1-5-32-544";
+	SID *sid = NULL;
+	TOKEN_MANDATORY_LABEL til;
+	HANDLE hCurrentToken, hNewToken;
+	if (MsIsNt() == false)
+	{
+		return NULL;
+	}
+	if (ms->nt->ConvertStringSidToSidA == NULL ||
+		ms->nt->OpenProcessToken == NULL ||
+		ms->nt->DuplicateTokenEx == NULL ||
+		ms->nt->GetTokenInformation == NULL ||
+		ms->nt->SetTokenInformation == NULL)
+	{
+		return NULL;
+	}
+
+	Zero(&til, sizeof(til));
+
+	if (ms->nt->ConvertStringSidToSidA(medium_sid, &sid) == false)
+	{
+		return NULL;
+	}
+
+	til.Label.Attributes = SE_GROUP_INTEGRITY;
+	til.Label.Sid = sid;
+
+	if (ms->nt->OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &hCurrentToken) == false)
+	{
+		LocalFree(sid);
+		return NULL;
+	}
+
+	if (ms->nt->DuplicateTokenEx(hCurrentToken, MAXIMUM_ALLOWED, NULL,
+		SecurityImpersonation, TokenPrimary, &hNewToken) == false)
+	{
+		CloseHandle(hCurrentToken);
+		LocalFree(sid);
+		return NULL;
+	}
+
+	if (ms->nt->SetTokenInformation(hNewToken, VistaTokenIntegrityLevel, &til,
+		sizeof(TOKEN_MANDATORY_LABEL) + GetLengthSid(sid)) == false)
+	{
+		CloseHandle(hNewToken);
+		CloseHandle(hCurrentToken);
+		LocalFree(sid);
+		return NULL;
+	}
+
+	CloseHandle(hCurrentToken);
+	LocalFree(sid);
+
+	return hNewToken;
+}
+
+// ファイルのデジタル署名をチェック
+bool MsCheckFileDigitalSignature(HWND hWnd, char *name, bool *danger)
+{
+	wchar_t tmp[MAX_PATH];
+
+	swprintf(tmp, sizeof(tmp), L"%S", name);
+
+	return MsCheckFileDigitalSignatureW(hWnd, tmp, danger);
+}
+bool MsCheckFileDigitalSignatureW(HWND hWnd, wchar_t *name, bool *danger)
+{
+	HRESULT ret = S_OK;
+	wchar_t *tmp;
+	LONG (WINAPI *_WinVerifyTrust)(HWND, GUID *, LPVOID) = NULL;
+	HINSTANCE hDll;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (danger != NULL)
+	{
+		*danger = false;
+	}
+
+	tmp = name;
+
+	hDll = LoadLibrary("Wintrust.dll");
+	if (hDll == NULL)
+	{
+		return false;
+	}
+
+	_WinVerifyTrust =
+		(LONG (__stdcall *)(HWND,GUID *,LPVOID))
+		GetProcAddress(hDll, "WinVerifyTrust");
+	if (_WinVerifyTrust == NULL)
+	{
+		FreeLibrary(hDll);
+		return false;
+	}
+	else
+	{
+		GUID action_id = WINTRUST_ACTION_GENERIC_VERIFY_V2;
+		WINTRUST_FILE_INFO file;
+		WINTRUST_DATA data;
+
+		Zero(&file, sizeof(file));
+		file.cbStruct = sizeof(file);
+		file.pcwszFilePath = tmp;
+
+		Zero(&data, sizeof(data));
+		data.cbStruct = sizeof(data);
+		data.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN;
+		data.dwUIChoice = (hWnd != NULL ? WTD_UI_NOGOOD : WTD_UI_NONE);
+		data.dwProvFlags = WTD_REVOCATION_CHECK_CHAIN;
+		data.dwUnionChoice = WTD_CHOICE_FILE;
+		data.pFile = &file;
+
+		ret = _WinVerifyTrust(hWnd, &action_id, &data);
+
+		if (ret == ERROR_SUCCESS && danger != NULL)
+		{
+			if (hWnd != NULL)
+			{
+				if (MsCheckFileDigitalSignatureW(NULL, name, NULL) == false)
+				{
+					// 危険なファイルだがユーザーが [OK] を選択してしまった
+					*danger = true;
+				}
+			}
+		}
+	}
+
+	FreeLibrary(hDll);
+
+	if (ret != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// WoW64 リダイレクションを有効または無効にする
+void MsSetWow64FileSystemRedirectionEnable(bool enable)
+{
+	if (MsIs64BitWindows() == false)
+	{
+		return;
+	}
+
+	if (ms->nt->Wow64EnableWow64FsRedirection == NULL)
+	{
+		return;
+	}
+
+	ms->nt->Wow64EnableWow64FsRedirection(enable ? 1 : 0);
+}
+
+// WoW64 リダイレクションを無効にする
+void *MsDisableWow64FileSystemRedirection()
+{
+	void *p = NULL;
+	if (MsIs64BitWindows() == false)
+	{
+		return NULL;
+	}
+
+	if (ms->nt->Wow64DisableWow64FsRedirection == NULL ||
+		ms->nt->Wow64RevertWow64FsRedirection == NULL)
+	{
+		return NULL;
+	}
+
+	if (ms->nt->Wow64DisableWow64FsRedirection(&p) == false)
+	{
+		return NULL;
+	}
+
+	if (p == NULL)
+	{
+		p = (void *)0x12345678;
+	}
+
+	return p;
+}
+
+// WoW64 リダイレクションを元に戻す
+void MsRestoreWow64FileSystemRedirection(void *p)
+{
+	// 引数チェック
+	if (p == NULL)
+	{
+		return;
+	}
+	if (p == (void *)0x12345678)
+	{
+		p = NULL;
+	}
+	if (MsIs64BitWindows() == false)
+	{
+		return;
+	}
+
+	if (ms->nt->Wow64DisableWow64FsRedirection == NULL ||
+		ms->nt->Wow64RevertWow64FsRedirection == NULL)
+	{
+		return;
+	}
+
+	ms->nt->Wow64RevertWow64FsRedirection(p);
+}
+
+// 現在 x64 版 Windows が動作しているかどうか取得
+bool MsIsX64()
+{
+	SYSTEM_INFO info;
+
+	if (MsIs64BitWindows() == false)
+	{
+		return false;
+	}
+	if (ms->nt->GetNativeSystemInfo == NULL)
+	{
+		return false;
+	}
+
+	Zero(&info, sizeof(info));
+	ms->nt->GetNativeSystemInfo(&info);
+
+	if (info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// 現在 IA64 版 Windows が動作しているかどうか取得
+bool MsIsIA64()
+{
+	if (MsIs64BitWindows() == false)
+	{
+		return false;
+	}
+
+	if (MsIsX64())
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// 64bit Windows かどうか取得
+bool MsIs64BitWindows()
+{
+	if (Is64())
+	{
+		return true;
+	}
+	else
+	{
+		if (MsIsNt() == false)
+		{
+			return false;
+		}
+		else
+		{
+			if (ms == NULL || ms->nt == NULL)
+			{
+				return false;
+			}
+
+			if (ms->nt->IsWow64Process == NULL)
+			{
+				return false;
+			}
+			else
+			{
+				bool b = false;
+				if (ms->nt->IsWow64Process(GetCurrentProcess(), &b) == false)
+				{
+					return false;
+				}
+				return b;
+			}
+		}
+	}
+}
+
+// Windows ファイアウォール登録
+void MsRegistWindowsFirewallEx2(char *title, char *exe)
+{
+	char *dir = MsGetExeDirName();
+	char tmp[MAX_PATH];
+	// 引数チェック
+	if (title == NULL || exe == NULL)
+	{
+		return;
+	}
+
+	ConbinePath(tmp, sizeof(tmp), dir, exe);
+
+	if (IsFileExists(tmp) == false)
+	{
+		return;
+	}
+
+	MsRegistWindowsFirewallEx(title, tmp);
+}
+void MsRegistWindowsFirewall(char *title)
+{
+	// 引数チェック
+	if (title == NULL)
+	{
+		return;
+	}
+
+	MsRegistWindowsFirewallEx(title, MsGetExeFileName());
+}
+void MsRegistWindowsFirewallEx(char *title, char *exe)
+{
+	char *data =
+		"Option Explicit\r\nConst NET_FW_PROFILE_DOMAIN = 0\r\nConst NET_FW_PROFILE_STANDARD = 1\r\n"
+		"Const NET_FW_SCOPE_ALL = 0\r\nConst NET_FW_IP_VERSION_ANY = 2\r\nDim fwMgr\r\n"
+		"Set fwMgr = CreateObject(\"HNetCfg.FwMgr\")\r\nDim profile\r\n"
+		"Set profile = fwMgr.LocalPolicy.CurrentProfile\r\nDim app\r\n"
+		"Set app = CreateObject(\"HNetCfg.FwAuthorizedApplication\")\r\n"
+		"app.ProcessImageFileName = \"$PATH$\"\r\napp.Name = \"$TITLE$\"\r\n"
+		"app.Scope = NET_FW_SCOPE_ALL\r\napp.IpVersion = NET_FW_IP_VERSION_ANY\r\n"
+		"app.Enabled = TRUE\r\nOn Error Resume Next\r\nprofile.AuthorizedApplications."
+		"Add app\r\n";
+	char *tmp;
+	UINT tmp_size;
+	char filename[MAX_PATH];
+	char cscript[MAX_PATH];
+	char arg[MAX_PATH];
+	UINT ostype;
+	IO *o;
+	char hash[MAX_PATH];
+	UCHAR hashbin[SHA1_SIZE];
+	// 引数チェック
+	if (title == NULL || exe == NULL)
+	{
+		return;
+	}
+
+	// OS チェック (Windows XP, Windows Server 2003, Windows Vista, Windows 7 以外では実施しない)
+	ostype = GetOsInfo()->OsType;
+	if (OS_IS_WINDOWS_NT(ostype) == false)
+	{
+		return;
+	}
+	if (GET_KETA(ostype, 100) != 3 && GET_KETA(ostype, 100) != 4 && GET_KETA(ostype, 100) != 5 && GET_KETA(ostype, 100) != 6)
+	{
+		return;
+	}
+
+	tmp_size = StrLen(data) * 4;
+	tmp = ZeroMalloc(tmp_size);
+
+	HashSha1(hashbin, exe, StrLen(exe));
+	BinToStr(hash, sizeof(hash), hashbin, 6);
+
+	ReplaceStrEx(tmp, tmp_size, data, "$TITLE$", title, false);
+	ReplaceStrEx(tmp, tmp_size, tmp, "$PATH$", exe, false);
+
+	Format(filename, sizeof(filename), "%s\\winfire_%s.vbs", MsGetMyTempDir(), hash);
+	o = FileCreate(filename);
+	FileWrite(o, tmp, StrLen(tmp));
+	FileClose(o);
+
+	Format(cscript, sizeof(cscript), "%s\\cscript.exe", MsGetSystem32Dir());
+	Format(arg, sizeof(arg), "\"%s\"", filename);
+
+	Run(cscript, arg, true, false);
+
+	Debug("cscript %s\n", arg);
+
+	Free(tmp);
+}
+
+// Vista 用ドライバインストーラの実行
+bool MsExecDriverInstaller(char *arg)
+{
+	wchar_t tmp[MAX_PATH];
+	wchar_t hamcore_dst[MAX_PATH];
+	wchar_t hamcore_src[MAX_PATH];
+	HANDLE h;
+	UINT retcode;
+	SHELLEXECUTEINFOW info;
+	wchar_t *src_exe;
+	wchar_t *arg_w;
+	// 引数チェック
+	if (arg == NULL)
+	{
+		return false;
+	}
+
+	UniFormat(hamcore_dst, sizeof(hamcore_dst), L"%s\\hamcore.utvpn", MsGetMyTempDirW());
+	UniFormat(hamcore_src, sizeof(hamcore_src), L"%s\\hamcore.utvpn", MsGetExeDirNameW());
+
+	// ファイル展開
+	src_exe = VISTA_DRIVER_INSTALLER_SRC;
+
+	if (MsIsX64())
+	{
+		src_exe = VISTA_DRIVER_INSTALLER_SRC_X64;
+	}
+	if (MsIsIA64())
+	{
+		src_exe = VISTA_DRIVER_INSTALLER_SRC_IA64;
+	}
+
+	UniFormat(tmp, sizeof(tmp), VISTA_DRIVER_INSTALLER_DST, MsGetMyTempDirW());
+
+	if (FileCopyW(src_exe, tmp) == false)
+	{
+		return false;
+	}
+
+	if (FileCopyW(hamcore_src, hamcore_dst) == false)
+	{
+		return false;
+	}
+
+	arg_w = CopyStrToUni(arg);
+
+	// 実行
+	Zero(&info, sizeof(info));
+	info.cbSize = sizeof(info);
+	info.lpVerb = L"open";
+	info.lpFile = tmp;
+	info.fMask = SEE_MASK_NOCLOSEPROCESS;
+	info.lpParameters = arg_w;
+	info.nShow = SW_SHOWNORMAL;
+	if (ShellExecuteExW(&info) == false)
+	{
+		Free(arg_w);
+		return false;
+	}
+
+	Free(arg_w);
+
+	h = info.hProcess;
+	retcode = 1;
+
+	while (true)
+	{
+		// 完了まで待機
+		WaitForSingleObject(h, INFINITE);
+
+		// 終了コードを取得
+		retcode = 1;
+		if (GetExitCodeProcess(h, &retcode) == false)
+		{
+			break;
+		}
+
+		if (retcode != STILL_ACTIVE)
+		{
+			break;
+		}
+	}
+
+	CloseHandle(h);
+
+	if (retcode & 1)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// 現在のスレッドのロケールを取得
+UINT MsGetThreadLocale()
+{
+	return (UINT)GetThreadLocale();
+}
+
+// 現在のコンソールの横幅を設定する
+UINT MsSetConsoleWidth(UINT size)
+{
+	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
+	CONSOLE_SCREEN_BUFFER_INFO info;
+	COORD c;
+	UINT old_x, old_y;
+	// 引数チェック
+	if (size == 0)
+	{
+		return 0;
+	}
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		return 0;
+	}
+
+	Zero(&info, sizeof(info));
+	if (GetConsoleScreenBufferInfo(h, &info) == false)
+	{
+		return 0;
+	}
+
+	old_x = info.dwSize.X;
+	old_y = info.dwSize.Y;
+
+	c.X = size;
+	c.Y = old_y;
+
+	SetConsoleScreenBufferSize(h, c);
+
+	return old_x;
+}
+
+// 現在のコンソールの横幅を取得する
+UINT MsGetConsoleWidth()
+{
+	HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
+	CONSOLE_SCREEN_BUFFER_INFO info;
+
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		return 80;
+	}
+
+	Zero(&info, sizeof(info));
+	if (GetConsoleScreenBufferInfo(h, &info) == false)
+	{
+		return 80;
+	}
+
+	return info.dwSize.X;
+}
+
+// MS-IME を無効にする
+bool MsDisableIme()
+{
+	HINSTANCE h;
+	bool ret = false;
+	char dll_name[MAX_PATH];
+	BOOL (WINAPI *_ImmDisableIME)(DWORD);
+
+	Format(dll_name, sizeof(dll_name), "%s\\imm32.dll", MsGetSystem32Dir());
+	h = MsLoadLibrary(dll_name);
+	if (h == NULL)
+	{
+		return false;
+	}
+
+	_ImmDisableIME = (BOOL (__stdcall *)(DWORD))GetProcAddress(h, "ImmDisableIME");
+
+	if (_ImmDisableIME != NULL)
+	{
+		ret = _ImmDisableIME(-1);
+	}
+
+	FreeLibrary(h);
+
+	return ret;
+}
+
+// 現在時刻を表示する
+void MsPrintTick()
+{
+	UINT tick = timeGetTime();
+	static UINT tick_init = 0;
+	if (tick_init == 0)
+	{
+		tick_init = tick;
+		tick = 0;
+	}
+	else
+	{
+		tick -= tick_init;
+	}
+
+	printf("[%u]\n", tick);
+}
+
+// LoadLibrary の hamcore 対応版 (データファイルとして読み込み)
+void *MsLoadLibraryAsDataFileW(wchar_t *name)
+{
+	BUF *b;
+	wchar_t tmp_dll_name[MAX_SIZE];
+	char hash_str[MAX_SIZE];
+	UCHAR hash[SHA1_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	Hash(hash, name, UniStrLen(name), true);
+
+	BinToStr(hash_str, sizeof(hash_str), hash, 4);
+
+	UniFormat(tmp_dll_name, sizeof(tmp_dll_name), L"%s\\%S.dll", MsGetMyTempDirW(), hash_str);
+
+	if (IsFileExistsW(tmp_dll_name) == false)
+	{
+		b = ReadDumpW(name);
+		if (b == NULL)
+		{
+			return NULL;
+		}
+
+		DumpBufW(b, tmp_dll_name);
+		FreeBuf(b);
+	}
+
+	return LoadLibraryExW(tmp_dll_name, NULL, LOAD_LIBRARY_AS_DATAFILE);
+}
+void *MsLoadLibraryAsDataFile(char *name)
+{
+	wchar_t name_w[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	StrToUni(name_w, sizeof(name_w), name);
+
+	return MsLoadLibraryAsDataFileW(name_w);
+}
+
+// LoadLibrary の hamcore 対応版
+void *MsLoadLibraryW(wchar_t *name)
+{
+	BUF *b;
+	wchar_t tmp_dll_name[MAX_SIZE];
+	char hash_str[MAX_SIZE];
+	UCHAR hash[SHA1_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	Hash(hash, name, UniStrSize(name), true);
+
+	BinToStr(hash_str, sizeof(hash_str), hash, 4);
+
+	UniFormat(tmp_dll_name, sizeof(tmp_dll_name), L"%s\\%S.dll", MsGetMyTempDirW(), hash_str);
+
+	if (IsFileExistsW(tmp_dll_name) == false)
+	{
+		b = ReadDumpW(name);
+		if (b == NULL)
+		{
+			return NULL;
+		}
+
+		DumpBufW(b, tmp_dll_name);
+		FreeBuf(b);
+	}
+
+	if (IsNt())
+	{
+		return LoadLibraryW(tmp_dll_name);
+	}
+	else
+	{
+		char tmp_dll_name_a[MAX_SIZE];
+		HINSTANCE ret;
+
+		UniToStr(tmp_dll_name_a, sizeof(tmp_dll_name_a), tmp_dll_name);
+
+		ret = LoadLibraryA(tmp_dll_name_a);
+
+		return ret;
+	}
+}
+void *MsLoadLibrary(char *name)
+{
+	wchar_t name_w[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	StrToUni(name_w, sizeof(name_w), name);
+
+	return MsLoadLibraryW(name_w);
+}
+
+// 単一のアダプタの取得
+MS_ADAPTER *MsGetAdapter(char *title)
+{
+	MS_ADAPTER_LIST *o;
+	MS_ADAPTER *ret = NULL;
+	UINT i;
+	// 引数チェック
+	if (title == NULL)
+	{
+		return NULL;
+	}
+
+	o = MsCreateAdapterList();
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < o->Num;i++)
+	{
+		if (StrCmpi(o->Adapters[i]->Title, title) == 0)
+		{
+			ret = MsCloneAdapter(o->Adapters[i]);
+			break;
+		}
+	}
+
+	MsFreeAdapterList(o);
+
+	return ret;
+}
+
+// 32 ビットオーバーフローチェック
+#define	CHECK_32BIT_OVERFLOW(old_value, new_value)				\
+{																\
+	if ((old_value) > (new_value))								\
+	{															\
+		(new_value) += ((UINT64)4294967296ULL);					\
+	}															\
+}
+
+// 指定したアダプタの TCP/IP 情報を取得する
+void MsGetAdapterTcpIpInformation(MS_ADAPTER *a)
+{
+	IP_ADAPTER_INFO *info, *info_top;
+	UINT info_size;
+	UINT ret;
+	// 引数チェック
+	if (a == NULL)
+	{
+		return;
+	}
+
+	if (w32net->GetAdaptersInfo == NULL)
+	{
+		return;
+	}
+
+	info_top = ZeroMalloc(sizeof(IP_ADAPTER_INFO));
+	info_size = sizeof(IP_ADAPTER_INFO);
+
+	ret = w32net->GetAdaptersInfo(info_top, &info_size);
+	if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW)
+	{
+		Free(info_top);
+		info_size *= 2;
+		info_top = ZeroMalloc(info_size);
+
+		if (w32net->GetAdaptersInfo(info_top, &info_size) != NO_ERROR)
+		{
+			Free(info_top);
+			return;
+		}
+	}
+	else if (ret != NO_ERROR)
+	{
+		Free(info_top);
+		return;
+	}
+
+	// 自分のエントリを検索する
+	info = info_top;
+
+	while (info != NULL)
+	{
+		if (info->Index == a->Index)
+		{
+			IP_ADDR_STRING *s;
+
+			// IP アドレス
+			a->NumIpAddress = 0;
+			s = &info->IpAddressList;
+			while (s != NULL)
+			{
+				if (a->NumIpAddress < MAX_MS_ADAPTER_IP_ADDRESS)
+				{
+					StrToIP(&a->IpAddresses[a->NumIpAddress], s->IpAddress.String);
+					StrToIP(&a->SubnetMasks[a->NumIpAddress], s->IpMask.String);
+					a->NumIpAddress++;
+				}
+				s = s->Next;
+			}
+
+			// ゲートウェイ
+			a->NumGateway = 0;
+			s = &info->GatewayList;
+			while (s != NULL)
+			{
+				if (a->NumGateway < MAX_MS_ADAPTER_IP_ADDRESS)
+				{
+					StrToIP(&a->Gateways[a->NumGateway], s->IpAddress.String);
+					a->NumGateway++;
+				}
+				s = s->Next;
+			}
+
+			// DHCP サーバー
+			a->UseDhcp = (info->DhcpEnabled == 0 ? false : true);
+			if (a->UseDhcp)
+			{
+				SYSTEMTIME st;
+
+				StrToIP(&a->DhcpServer, info->DhcpServer.IpAddress.String);
+				TimeToSystem(&st, info->LeaseObtained);
+				a->DhcpLeaseStart = SystemToUINT64(&st);
+
+				TimeToSystem(&st, info->LeaseExpires);
+				a->DhcpLeaseExpires = SystemToUINT64(&st);
+			}
+
+			// WINS サーバー
+			a->UseWins = info->HaveWins;
+			if (a->UseWins)
+			{
+				StrToIP(&a->PrimaryWinsServer, info->PrimaryWinsServer.IpAddress.String);
+				StrToIP(&a->SecondaryWinsServer, info->SecondaryWinsServer.IpAddress.String);
+			}
+
+			StrCpy(a->Guid, sizeof(a->Guid), info->AdapterName);
+
+			a->Info = true;
+
+			break;
+		}
+
+		info = info->Next;
+	}
+
+	Free(info_top);
+}
+
+// アダプタリストの生成
+MS_ADAPTER_LIST *MsCreateAdapterList()
+{
+	return MsCreateAdapterListEx(false);
+}
+MS_ADAPTER_LIST *MsCreateAdapterListEx(bool no_info)
+{
+	MS_ADAPTER_LIST *ret;
+
+	if (no_info)
+	{
+		ret = MsCreateAdapterListInnerEx(true);
+
+		return ret;
+	}
+
+	Lock(lock_adapter_list);
+	{
+		MS_ADAPTER_LIST *old = last_adapter_list;
+		UINT i;
+
+		// 新しくアダプタリストを取ってくる
+		ret = MsCreateAdapterListInner();
+
+		if (ret == NULL)
+		{
+			Unlock(lock_adapter_list);
+			return NULL;
+		}
+
+		// 取ってきたアダプタリストの各エントリについて、前回取得したものが
+		// 存在するかどうかチェックする
+		for (i = 0;i < ret->Num;i++)
+		{
+			UINT j;
+			for (j = 0;j < old->Num;j++)
+			{
+				MS_ADAPTER *o = old->Adapters[j];
+				MS_ADAPTER *n = ret->Adapters[i];
+
+				if (StrCmpi(o->Title, n->Title) == 0)
+				{
+					// 古いもののほうが値が小さい場合、インクリメントする
+					CHECK_32BIT_OVERFLOW(o->RecvBytes, n->RecvBytes);
+					CHECK_32BIT_OVERFLOW(o->RecvPacketsBroadcast, n->RecvPacketsBroadcast);
+					CHECK_32BIT_OVERFLOW(o->RecvPacketsUnicast, n->RecvPacketsUnicast);
+					CHECK_32BIT_OVERFLOW(o->SendBytes, n->SendBytes);
+					CHECK_32BIT_OVERFLOW(o->SendPacketsBroadcast, n->SendPacketsBroadcast);
+					CHECK_32BIT_OVERFLOW(o->SendPacketsUnicast, n->SendPacketsUnicast);
+					break;
+				}
+			}
+		}
+
+		// 古いアダプタリストを解放する
+		MsFreeAdapterList(old);
+
+		// 新しく取得したアダプタリストのクローンを保存しておく
+		last_adapter_list = MsCloneAdapterList(ret);
+	}
+	Unlock(lock_adapter_list);
+
+	return ret;
+}
+
+// アダプタリストモジュールの初期化
+void MsInitAdapterListModule()
+{
+	lock_adapter_list = NewLock(NULL);
+
+	last_adapter_list = MsCreateAdapterListInner();
+}
+
+// アダプタリストモジュールの解放
+void MsFreeAdapterListModule()
+{
+	if (last_adapter_list != NULL)
+	{
+		MsFreeAdapterList(last_adapter_list);
+		last_adapter_list = NULL;
+	}
+
+	DeleteLock(lock_adapter_list);
+	lock_adapter_list = NULL;
+}
+
+// アダプタリストのクローン
+MS_ADAPTER_LIST *MsCloneAdapterList(MS_ADAPTER_LIST *o)
+{
+	MS_ADAPTER_LIST *ret;
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	ret = ZeroMalloc(sizeof(MS_ADAPTER_LIST));
+	ret->Num = o->Num;
+	ret->Adapters = ZeroMalloc(sizeof(MS_ADAPTER *) * ret->Num);
+
+	for (i = 0;i < ret->Num;i++)
+	{
+		ret->Adapters[i] = ZeroMalloc(sizeof(MS_ADAPTER));
+		Copy(ret->Adapters[i], o->Adapters[i], sizeof(MS_ADAPTER));
+	}
+
+	return ret;
+}
+
+// アダプタのクローン
+MS_ADAPTER *MsCloneAdapter(MS_ADAPTER *a)
+{
+	MS_ADAPTER *ret;
+	// 引数チェック
+	if (a == NULL)
+	{
+		return NULL;
+	}
+
+	ret = ZeroMalloc(sizeof(MS_ADAPTER));
+	Copy(ret, a, sizeof(MS_ADAPTER));
+
+	return ret;
+}
+
+// アダプタリストの作成
+MS_ADAPTER_LIST *MsCreateAdapterListInner()
+{
+	return MsCreateAdapterListInnerEx(false);
+}
+MS_ADAPTER_LIST *MsCreateAdapterListInnerEx(bool no_info)
+{
+	LIST *o;
+	UINT i;
+	UINT retcode;
+	MIB_IFTABLE *table;
+	UINT table_size = sizeof(MIB_IFTABLE);
+	MS_ADAPTER_LIST *ret;
+
+	table = ZeroMalloc(table_size);
+
+	if (w32net->GetIfTable == NULL)
+	{
+		return ZeroMalloc(sizeof(MS_ADAPTER_LIST));
+	}
+
+	retcode = w32net->GetIfTable(table, &table_size, TRUE);
+	if (retcode == ERROR_INSUFFICIENT_BUFFER || retcode == ERROR_BUFFER_OVERFLOW)
+	{
+		Free(table);
+		table_size *= 2;
+		table = ZeroMalloc(table_size);
+		if (w32net->GetIfTable(table, &table_size, TRUE) != NO_ERROR)
+		{
+			Free(table);
+			return NULL;
+		}
+	}
+	else if (retcode != NO_ERROR)
+	{
+		Free(table);
+		return NULL;
+	}
+
+	o = NewListFast(NULL);
+
+	for (i = 0;i < table->dwNumEntries;i++)
+	{
+		MIB_IFROW *r = &table->table[i];
+		char title[MAX_PATH];
+		UINT num = 0;
+		MS_ADAPTER *a;
+		UINT j;
+
+		//if (r->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED || r->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL)
+		{
+			//if (r->dwType & IF_TYPE_ETHERNET_CSMACD)
+			{
+				for (j = 1;;j++)
+				{
+					UINT k;
+					bool exists;
+					if (j == 1)
+					{
+						StrCpy(title, sizeof(title), (char *)r->bDescr);
+					}
+					else
+					{
+						Format(title, sizeof(title), "%s (%u)", (char *)r->bDescr, j);
+					}
+
+					exists = false;
+
+					for (k = 0;k < LIST_NUM(o);k++)
+					{
+						MS_ADAPTER *a = LIST_DATA(o, k);
+
+						if (StrCmpi(a->Title, title) == 0)
+						{
+							exists = true;
+							break;
+						}
+					}
+
+					if (exists == false)
+					{
+						break;
+					}
+				}
+
+				a = ZeroMalloc(sizeof(MS_ADAPTER));
+
+				// アダプタ情報作成
+				StrCpy(a->Title, sizeof(a->Title), title);
+				a->Index = r->dwIndex;
+				a->Type = r->dwType;
+				a->Status = r->dwOperStatus;
+				a->Mtu = r->dwMtu;
+				a->Speed = r->dwSpeed;
+				a->AddressSize = MIN(sizeof(a->Address), r->dwPhysAddrLen);
+				Copy(a->Address, r->bPhysAddr, a->AddressSize);
+				a->RecvBytes = r->dwInOctets;
+				a->RecvPacketsBroadcast = r->dwInNUcastPkts;
+				a->RecvPacketsUnicast = r->dwInUcastPkts;
+				a->SendBytes = r->dwOutOctets;
+				a->SendPacketsBroadcast = r->dwOutNUcastPkts;
+				a->SendPacketsUnicast = r->dwOutUcastPkts;
+
+				// TCP/IP 情報取得
+				if (no_info == false)
+				{
+					MsGetAdapterTcpIpInformation(a);
+				}
+
+				Add(o, a);
+			}
+		}
+	}
+
+	ret = ZeroMalloc(sizeof(MS_ADAPTER_LIST));
+	ret->Num = LIST_NUM(o);
+	ret->Adapters = ToArray(o);
+
+	ReleaseList(o);
+	Free(table);
+
+	return ret;
+}
+
+// アダプタリストの解放
+void MsFreeAdapterList(MS_ADAPTER_LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < o->Num;i++)
+	{
+		MsFreeAdapter(o->Adapters[i]);
+	}
+	Free(o->Adapters);
+
+	Free(o);
+}
+
+// アダプタ情報の解放
+void MsFreeAdapter(MS_ADAPTER *a)
+{
+	// 引数チェック
+	if (a == NULL)
+	{
+		return;
+	}
+
+	Free(a);
+}
+
+// アダプタの状態文字列を取得する
+wchar_t *MsGetAdapterStatusStr(UINT status)
+{
+	wchar_t *ret;
+
+	switch (status)
+	{
+	case MIB_IF_OPER_STATUS_NON_OPERATIONAL:
+		ret = _UU("MS_NON_OPERATIONAL");
+		break;
+
+	case MIB_IF_OPER_STATUS_UNREACHABLE:
+		ret = _UU("MS_UNREACHABLE");
+		break;
+
+	case MIB_IF_OPER_STATUS_DISCONNECTED:
+		ret = _UU("MS_DISCONNECTED");
+		break;
+
+	case MIB_IF_OPER_STATUS_CONNECTING:
+		ret = _UU("MS_CONNECTING");
+		break;
+
+	case MIB_IF_OPER_STATUS_CONNECTED:
+		ret = _UU("MS_CONNECTED");
+		break;
+
+	default:
+		ret = _UU("MS_OPERATIONAL");
+		break;
+	}
+
+	return ret;
+}
+
+// アダプタの種類文字列を取得する
+wchar_t *MsGetAdapterTypeStr(UINT type)
+{
+	wchar_t *ret;
+
+	switch (type)
+	{
+	case MIB_IF_TYPE_ETHERNET:
+		ret = _UU("MS_ETHERNET");
+		break;
+
+	case MIB_IF_TYPE_TOKENRING:
+		ret = _UU("MS_TOKENRING");
+		break;
+
+	case MIB_IF_TYPE_FDDI:
+		ret = _UU("MS_FDDI");
+		break;
+
+	case MIB_IF_TYPE_PPP:
+		ret = _UU("MS_PPP");
+		break;
+
+	case MIB_IF_TYPE_LOOPBACK:
+		ret = _UU("MS_LOOPBACK");
+		break;
+
+	case MIB_IF_TYPE_SLIP:
+		ret = _UU("MS_SLIP");
+		break;
+
+	default:
+		ret = _UU("MS_OTHER");
+		break;
+	}
+
+	return ret;
+}
+
+// 自分自身の EXE の自分以外のインスタンスをすべて終了する
+void MsKillOtherInstance()
+{
+	MsKillOtherInstanceEx(NULL);
+}
+void MsKillOtherInstanceEx(char *exclude_svcname)
+{
+	UINT me, i;
+	wchar_t me_path[MAX_PATH];
+	wchar_t me_path_short[MAX_PATH];
+	LIST *o = MsGetProcessList();
+	UINT e_procid = 0;
+	UINT e_procid2 = 0;
+
+	if (exclude_svcname != NULL)
+	{
+		e_procid = MsReadCallingServiceManagerProcessId(exclude_svcname, false);
+		e_procid2 = MsReadCallingServiceManagerProcessId(exclude_svcname, true);
+	}
+
+	me = MsGetProcessId();
+
+	MsGetCurrentProcessExeNameW(me_path, sizeof(me_path));
+	MsGetShortPathNameW(me_path, me_path_short, sizeof(me_path_short));
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		MS_PROCESS *p = LIST_DATA(o, i);
+		if (p->ProcessId != me)
+		{
+			if ((e_procid == 0 || (e_procid != p->ProcessId)) && (e_procid2 == 0 || (e_procid2 != p->ProcessId)))
+			{
+				wchar_t tmp[MAX_PATH];
+				MsGetShortPathNameW(p->ExeFilenameW, tmp, sizeof(tmp));
+				if (UniStrCmpi(me_path_short, tmp) == 0)
+				{
+					MsKillProcess(p->ProcessId);
+				}
+			}
+		}
+	}
+
+	MsFreeProcessList(o);
+}
+
+// 短いファイル名を取得する
+bool MsGetShortPathNameA(char *long_path, char *short_path, UINT short_path_size)
+{
+	// 引数チェック
+	if (long_path == NULL || short_path == NULL)
+	{
+		return false;
+	}
+
+	if (GetShortPathNameA(long_path, short_path, short_path_size) == 0)
+	{
+		StrCpy(short_path, short_path_size, long_path);
+		return false;
+	}
+
+	return true;
+}
+bool MsGetShortPathNameW(wchar_t *long_path, wchar_t *short_path, UINT short_path_size)
+{
+	// 引数チェック
+	if (long_path == NULL || short_path == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char short_path_a[MAX_SIZE];
+		char long_path_a[MAX_SIZE];
+		bool ret;
+
+		UniToStr(long_path_a, sizeof(long_path_a), long_path);
+
+		ret = MsGetShortPathNameA(long_path_a, short_path_a, sizeof(short_path_a));
+
+		StrToUni(short_path, short_path_size, short_path_a);
+
+		return ret;
+	}
+
+	if (GetShortPathNameW(long_path, short_path, short_path_size) == 0)
+	{
+		UniStrCpy(short_path, short_path_size, long_path);
+		return false;
+	}
+
+	return true;
+}
+
+// 指定したプロセスの強制終了
+bool MsKillProcess(UINT id)
+{
+	HANDLE h;
+	// 引数チェック
+	if (id == 0)
+	{
+		return false;
+	}
+
+	h = OpenProcess(PROCESS_TERMINATE, FALSE, id);
+	if (h == NULL)
+	{
+		return false;
+	}
+
+	if (TerminateProcess(h, 0) == FALSE)
+	{
+		CloseHandle(h);
+		return false;
+	}
+
+	CloseHandle(h);
+
+	return true;
+}
+
+// 現在の EXE ファイル名を取得
+void MsGetCurrentProcessExeName(char *name, UINT size)
+{
+	UINT id;
+	LIST *o;
+	MS_PROCESS *p;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	id = MsGetCurrentProcessId();
+	o = MsGetProcessList();
+	p = MsSearchProcessById(o, id);
+	if (p != NULL)
+	{
+		p = MsSearchProcessById(o, id);
+		StrCpy(name, size, p->ExeFilename);
+	}
+	else
+	{
+		StrCpy(name, size, MsGetExeFileName());
+	}
+	MsFreeProcessList(o);
+}
+void MsGetCurrentProcessExeNameW(wchar_t *name, UINT size)
+{
+	UINT id;
+	LIST *o;
+	MS_PROCESS *p;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	id = MsGetCurrentProcessId();
+	o = MsGetProcessList();
+	p = MsSearchProcessById(o, id);
+	if (p != NULL)
+	{
+		p = MsSearchProcessById(o, id);
+		UniStrCpy(name, size, p->ExeFilenameW);
+	}
+	else
+	{
+		UniStrCpy(name, size, MsGetExeFileNameW());
+	}
+	MsFreeProcessList(o);
+}
+
+// プロセスをプロセス ID から検索する
+MS_PROCESS *MsSearchProcessById(LIST *o, UINT id)
+{
+	MS_PROCESS *p, t;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	Zero(&t, sizeof(t));
+	t.ProcessId = id;
+
+	p = Search(o, &t);
+
+	return p;
+}
+
+// プロセスリスト比較
+int MsCompareProcessList(void *p1, void *p2)
+{
+	MS_PROCESS *e1, *e2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	e1 = *(MS_PROCESS **)p1;
+	e2 = *(MS_PROCESS **)p2;
+	if (e1 == NULL || e2 == NULL)
+	{
+		return 0;
+	}
+
+	if (e1->ProcessId > e2->ProcessId)
+	{
+		return 1;
+	}
+	else if (e1->ProcessId < e2->ProcessId)
+	{
+		return -1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+// プロセスリストの表示
+void MsPrintProcessList(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		MS_PROCESS *p = LIST_DATA(o, i);
+		UniPrint(L"%-4u: %s\n", p->ProcessId, p->ExeFilenameW);
+	}
+}
+
+// プロセスリストの解放
+void MsFreeProcessList(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		MS_PROCESS *p = LIST_DATA(o, i);
+		Free(p);
+	}
+
+	ReleaseList(o);
+}
+
+// プロセスリストの取得 (WinNT 用)
+LIST *MsGetProcessListNt()
+{
+	LIST *o;
+	UINT max = 16384;
+	DWORD *processes;
+	UINT needed, num;
+	UINT i;
+
+	o = NewListFast(MsCompareProcessList);
+
+	if (ms->nt->EnumProcesses == NULL)
+	{
+		return o;
+	}
+
+	processes = ZeroMalloc(sizeof(DWORD) * max);
+
+	if (ms->nt->EnumProcesses(processes, sizeof(DWORD) * max, &needed) == FALSE)
+	{
+		Free(processes);
+		return NULL;
+	}
+
+	num = needed / sizeof(DWORD);
+
+	for (i = 0;i < num;i++)
+	{
+		UINT id = processes[i];
+		HANDLE h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
+			false, id);
+
+		if (h != NULL)
+		{
+			HINSTANCE hInst = NULL;
+			DWORD needed;
+			if (ms->nt->EnumProcessModules(h, &hInst, sizeof(hInst), &needed))
+			{
+				MS_PROCESS *p = ZeroMalloc(sizeof(MS_PROCESS));
+				ms->nt->GetModuleFileNameExA(h, hInst, p->ExeFilename, sizeof(p->ExeFilename) - 1);
+				ms->nt->GetModuleFileNameExW(h, hInst, p->ExeFilenameW, sizeof(p->ExeFilenameW) / sizeof(wchar_t) - 1);
+				p->ProcessId = id;
+				Add(o, p);
+			}
+			CloseHandle(h);
+		}
+	}
+
+	Sort(o);
+
+	Free(processes);
+
+	return o;
+}
+
+// プロセスリストの取得 (Win9x 用)
+LIST *MsGetProcessList9x()
+{
+	HANDLE h;
+	LIST *o;
+	HANDLE (WINAPI *CreateToolhelp32Snapshot)(DWORD, DWORD);
+	BOOL (WINAPI *Process32First)(HANDLE, LPPROCESSENTRY32);
+	BOOL (WINAPI *Process32Next)(HANDLE, LPPROCESSENTRY32);
+
+	CreateToolhelp32Snapshot =
+		(HANDLE (__stdcall *)(DWORD,DWORD))
+		GetProcAddress(ms->hKernel32, "CreateToolhelp32Snapshot");
+	Process32First =
+		(BOOL (__stdcall *)(HANDLE,LPPROCESSENTRY32))
+		GetProcAddress(ms->hKernel32, "Process32First");
+	Process32Next =
+		(BOOL (__stdcall *)(HANDLE,LPPROCESSENTRY32))
+		GetProcAddress(ms->hKernel32, "Process32Next");
+
+	o = NewListFast(MsCompareProcessList);
+
+	if (CreateToolhelp32Snapshot != NULL && Process32First != NULL && Process32Next != NULL)
+	{
+		h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+		if (h != INVALID_HANDLE_VALUE)
+		{
+			PROCESSENTRY32 e;
+			Zero(&e, sizeof(e));
+			e.dwSize = sizeof(e);
+
+			if (Process32First(h, &e))
+			{
+				while (true)
+				{
+					MS_PROCESS *p = ZeroMalloc(sizeof(MS_PROCESS));
+					StrCpy(p->ExeFilename, sizeof(p->ExeFilename), e.szExeFile);
+					StrToUni(p->ExeFilenameW, sizeof(p->ExeFilenameW), p->ExeFilename);
+					p->ProcessId = e.th32ProcessID;
+					Add(o, p);
+					if (Process32Next(h, &e) == false)
+					{
+						break;
+					}
+				}
+			}
+			CloseHandle(h);
+		}
+	}
+
+	Sort(o);
+
+	return o;
+}
+
+// プロセスリストの取得
+LIST *MsGetProcessList()
+{
+	if (MsIsNt() == false)
+	{
+		// Windows 9x
+		return MsGetProcessList9x();
+	}
+	else
+	{
+		// Windows NT, 2000, XP
+		return MsGetProcessListNt();
+	}
+}
+
+// 現在のスレッドを 1 つの CPU で動作するように強制する
+void MsSetThreadSingleCpu()
+{
+	SetThreadAffinityMask(GetCurrentThread(), 1);
+}
+
+// サウンドの再生
+void MsPlaySound(char *name)
+{
+	char tmp[MAX_SIZE];
+	char wav[MAX_SIZE];
+	char *temp;
+	BUF *b;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	Format(tmp, sizeof(tmp), "|%s", name);
+
+	b = ReadDump(tmp);
+	if (b == NULL)
+	{
+		return;
+	}
+
+	temp = MsGetMyTempDir();
+	Format(wav, sizeof(tmp), "%s\\%s", temp, name);
+	DumpBuf(b, wav);
+
+	PlaySound(wav, NULL, SND_ASYNC | SND_FILENAME | SND_NODEFAULT);
+
+	FreeBuf(b);
+}
+
+// タスクトレイにアイコンを表示する
+void MsShowIconOnTray(HWND hWnd, HICON icon, wchar_t *tooltip, UINT msg)
+{
+	// 引数チェック
+	if (hWnd == NULL || icon == NULL)
+	{
+		return;
+	}
+
+	if (MsIsNt() == false)
+	{
+		Zero(&nid, sizeof(nid));
+		nid.cbSize = sizeof(nid);
+		nid.hWnd = hWnd;
+		nid.uID = 1;
+		nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
+		nid.uCallbackMessage = msg;
+		nid.hIcon = icon;
+		UniToStr(nid.szTip, sizeof(nid.szTip), tooltip);
+		Shell_NotifyIcon(NIM_ADD, &nid);
+	}
+	else
+	{
+		Zero(&nid_nt, sizeof(nid_nt));
+		nid_nt.cbSize = sizeof(nid_nt);
+		nid_nt.hWnd = hWnd;
+		nid_nt.uID = 1;
+		nid_nt.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP | NIF_INFO;
+		nid_nt.uCallbackMessage = msg;
+		nid_nt.hIcon = icon;
+		UniStrCpy(nid_nt.szTip, sizeof(nid_nt.szTip), tooltip);
+		Shell_NotifyIconW(NIM_ADD, &nid_nt);
+	}
+
+	tray_inited = true;
+}
+
+// タスクトレイが初期化されているかどうか確認する
+bool MsIsTrayInited()
+{
+	return tray_inited;
+}
+
+// タスクトレイのアイコンを復元する
+void MsRestoreIconOnTray()
+{
+	if (tray_inited == false)
+	{
+		return;
+	}
+
+	if (MsIsNt() == false)
+	{
+		Shell_NotifyIcon(NIM_ADD, &nid);
+	}
+	else
+	{
+		Shell_NotifyIconW(NIM_ADD, &nid_nt);
+	}
+}
+
+// タスクトレイのアイコンを変更する (いけー)
+void MsChangeIconOnTrayEx2(void *icon, wchar_t *tooltip, wchar_t *info_title, wchar_t *info, UINT info_flags)
+{
+	MsChangeIconOnTrayEx((HICON)icon, tooltip, info_title, info, info_flags);
+}
+
+// タスクトレイのアイコンを変更する
+void MsChangeIconOnTray(HICON icon, wchar_t *tooltip)
+{
+	MsChangeIconOnTrayEx(icon, tooltip, NULL, NULL, NIIF_NONE);
+}
+void MsChangeIconOnTrayEx(HICON icon, wchar_t *tooltip, wchar_t *info_title, wchar_t *info, UINT info_flags)
+{
+	bool changed = false;
+
+	if (tray_inited == false)
+	{
+		return;
+	}
+
+	if (icon != NULL)
+	{
+		if (MsIsNt() == false)
+		{
+			if (nid.hIcon != icon)
+			{
+				changed = true;
+				nid.hIcon = icon;
+			}
+		}
+		else
+		{
+			if (nid_nt.hIcon != icon)
+			{
+				changed = true;
+				nid_nt.hIcon = icon;
+			}
+		}
+	}
+
+	if (tooltip != NULL)
+	{
+		if (MsIsNt() == false)
+		{
+			char tmp[MAX_SIZE];
+
+			UniToStr(tmp, sizeof(tmp), tooltip);
+
+			if (StrCmp(nid.szTip, tmp) != 0)
+			{
+				StrCpy(nid.szTip, sizeof(nid.szTip), tmp);
+				changed = true;
+			}
+		}
+		else
+		{
+			wchar_t tmp[MAX_SIZE];
+
+			UniStrCpy(tmp, sizeof(tmp), tooltip);
+
+			if (UniStrCmp(nid_nt.szTip, tmp) != 0)
+			{
+				UniStrCpy(nid_nt.szTip, sizeof(nid_nt.szTip), tmp);
+				changed = true;
+			}
+		}
+	}
+
+	if (info_title != NULL && info != NULL)
+	{
+		if (MsIsNt() == false)
+		{
+			char tmp1[MAX_SIZE];
+			char tmp2[MAX_PATH];
+
+			UniToStr(tmp1, sizeof(tmp1), info_title);
+			UniToStr(tmp2, sizeof(tmp2), info);
+
+			if (StrCmp(nid.szInfo, tmp1) != 0 ||
+				StrCmp(nid.szInfoTitle, tmp2) != 0)
+			{
+				StrCpy(nid.szInfo, sizeof(nid.szInfo), tmp1);
+				StrCpy(nid.szInfoTitle, sizeof(nid.szInfoTitle), tmp2);
+				nid.dwInfoFlags = info_flags;
+
+				changed = true;
+			}
+		}
+		else
+		{
+			wchar_t tmp1[MAX_SIZE];
+			wchar_t tmp2[MAX_PATH];
+
+			UniStrCpy(tmp1, sizeof(tmp1), info_title);
+			UniStrCpy(tmp2, sizeof(tmp2), info);
+
+			if (UniStrCmp(nid_nt.szInfo, tmp1) != 0 ||
+				UniStrCmp(nid_nt.szInfoTitle, tmp2) != 0)
+			{
+				UniStrCpy(nid_nt.szInfo, sizeof(nid_nt.szInfo), tmp1);
+				UniStrCpy(nid_nt.szInfoTitle, sizeof(nid_nt.szInfoTitle), tmp2);
+				nid_nt.dwInfoFlags = info_flags;
+
+				changed = true;
+			}
+		}
+	}
+
+	if (changed)
+	{
+		if (MsIsNt() == false)
+		{
+			Shell_NotifyIcon(NIM_MODIFY, &nid);
+		}
+		else
+		{
+			Shell_NotifyIconW(NIM_MODIFY, &nid_nt);
+		}
+	}
+}
+
+// タスクトレイのアイコンを削除する
+void MsHideIconOnTray()
+{
+	if (MsIsNt() == false)
+	{
+		Shell_NotifyIcon(NIM_DELETE, &nid);
+	}
+	else
+	{
+		Shell_NotifyIconW(NIM_DELETE, &nid_nt);
+	}
+
+	tray_inited = false;
+}
+
+// メニュー項目の挿入
+bool MsInsertMenu(HMENU hMenu, UINT pos, UINT flags, UINT_PTR id_new_item, wchar_t *lp_new_item)
+{
+	bool ret;
+
+	if (MsIsNt())
+	{
+		ret = InsertMenuW(hMenu, pos, flags, id_new_item, lp_new_item);
+	}
+	else
+	{
+		char *s = CopyUniToStr(lp_new_item);
+		ret = InsertMenuA(hMenu, pos, flags, id_new_item, s);
+		Free(s);
+	}
+
+	return ret;
+}
+
+// メニュー項目の追加
+bool MsAppendMenu(HMENU hMenu, UINT flags, UINT_PTR id, wchar_t *str)
+{
+	bool ret;
+
+	if (MsIsNt())
+	{
+		ret = AppendMenuW(hMenu, flags, id, str);
+	}
+	else
+	{
+		char *s = CopyUniToStr(str);
+		ret = AppendMenuA(hMenu, flags, id, s);
+		Free(s);
+	}
+
+	return ret;
+}
+
+// メニュー表示
+void MsUserModeTrayMenu(HWND hWnd)
+{
+	HMENU h;
+	POINT p;
+	wchar_t tmp[MAX_SIZE];
+	wchar_t caption[MAX_SIZE];
+	// 引数チェック
+	if (hWnd == NULL)
+	{
+		return;
+	}
+
+	// メニューを作成する
+	h = CreatePopupMenu();
+	MsAppendMenu(h, MF_ENABLED | MF_STRING, 10001, _UU("SVC_USERMODE_MENU_1"));
+	MsAppendMenu(h, MF_SEPARATOR, 10002, NULL);
+
+	if (MsIsNt())
+	{
+		GetWindowTextW(hWnd, caption, sizeof(caption));
+	}
+	else
+	{
+		char tmp[MAX_SIZE];
+		GetWindowTextA(hWnd, tmp, sizeof(tmp));
+		StrToUni(caption, sizeof(caption), tmp);
+	}
+
+	UniFormat(tmp, sizeof(tmp), _UU("SVC_USERMODE_MENU_2"), caption);
+	MsAppendMenu(h, MF_ENABLED | MF_STRING, 10003, tmp);
+
+	// メニューを表示する
+	GetCursorPos(&p);
+
+	SetForegroundWindow(hWnd);
+	TrackPopupMenu(h, TPM_LEFTALIGN, p.x, p.y, 0, hWnd, NULL);
+	PostMessage(hWnd, WM_NULL, 0, 0);
+
+	DestroyMenu(h);
+}
+
+// ユーザーモード用ウインドウプロシージャ
+LRESULT CALLBACK MsUserModeWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+	wchar_t tmp[MAX_SIZE];
+	char title[MAX_SIZE];
+	wchar_t title_w[MAX_SIZE];
+	char value_name[MAX_SIZE];
+	static UINT taskbar_msg = 0;
+	// 引数チェック
+	if (hWnd == NULL)
+	{
+		return 0;
+	}
+
+	if (msg == taskbar_msg && taskbar_msg != 0)
+	{
+		// タスクバーが再生成された
+		if (MsRegReadInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, value_name) == 0 &&
+			service_for_9x_mode == false)
+		{
+			MsRestoreIconOnTray();
+		}
+	}
+
+	switch (msg)
+	{
+	case WM_ENDSESSION:
+		// 再開
+		if (wParam == false)
+		{
+			break;
+		}
+	case WM_CREATE:
+		// 開始
+		exiting = false;
+		g_start();
+		GetWindowText(hWnd, title, sizeof(title));
+		StrToUni(title_w, sizeof(title_w), title);
+		UniFormat(tmp, sizeof(tmp), _UU("SVC_TRAY_TOOLTIP"), title);
+
+		if (taskbar_msg == 0)
+		{
+			taskbar_msg = RegisterWindowMessage("TaskbarCreated");
+		}
+
+		Format(value_name, sizeof(value_name), SVC_HIDETRAY_REG_VALUE, title_w);
+		if (MsRegReadInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, value_name) == 0 &&
+			service_for_9x_mode == false)
+		{
+			MsShowIconOnTray(hWnd, tray_icon, tmp, WM_APP + 33);
+		}
+
+		break;
+	case WM_APP + 33:
+		if (wParam == 1)
+		{
+			// タスクトレイのアイコンに対する操作
+			switch (lParam)
+			{
+			case WM_RBUTTONDOWN:
+				// 右クリック
+				MsUserModeTrayMenu(hWnd);
+				break;
+			case WM_LBUTTONDBLCLK:
+				// 左ダブルクリック
+				break;
+			}
+		}
+		break;
+	case WM_LBUTTONDOWN:
+		MsUserModeTrayMenu(hWnd);
+		break;
+	case WM_QUERYENDSESSION:
+		if (exiting == false)
+		{
+			exiting = true;
+			MsHideIconOnTray();
+			g_stop();
+			DestroyWindow(hWnd);
+		}
+		return TRUE;
+	case WM_CLOSE:
+		// 停止
+		if (exiting == false)
+		{
+			exiting = true;
+			g_stop();
+			MsHideIconOnTray();
+			DestroyWindow(hWnd);
+		}
+		break;
+	case WM_DESTROY:
+		wnd_end = true;
+		break;
+	case WM_COMMAND:
+		switch (wParam)
+		{
+		case 10001:
+			GetWindowText(hWnd, title, sizeof(title));
+			StrToUni(title_w, sizeof(title_w), title);
+			// 確認メッセージの表示
+			if (MsgBoxEx(hWnd, MB_ICONINFORMATION | MB_OKCANCEL | MB_DEFBUTTON2 |
+				MB_SYSTEMMODAL, _UU("SVC_HIDE_TRAY_MSG"), title, title) == IDOK)
+			{
+				char tmp[MAX_SIZE];
+				Format(tmp, sizeof(tmp), SVC_HIDETRAY_REG_VALUE, title_w);
+				// レジストリに書き込む
+				MsRegWriteInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, tmp, 1);
+				// アイコンを消す
+				MsHideIconOnTray();
+			}
+			break;
+		case 10003:
+			SendMessage(hWnd, WM_CLOSE, 0, 0);
+			break;
+		}
+		break;
+	}
+	return DefWindowProc(hWnd, msg, wParam, lParam);
+}
+
+// PenCore.dll の名前の取得
+char *MsGetPenCoreDllFileName()
+{
+	return PENCORE_DLL_NAME;
+}
+
+// これがユーザーモードかどうか取得
+bool MsIsUserMode()
+{
+	return is_usermode;
+}
+
+// サービス側からユーザーモードの終了を指示
+void MsStopUserModeFromService()
+{
+	if (hWndUsermode != NULL)
+	{
+		PostMessage(hWndUsermode, WM_CLOSE, 0, 0);
+	}
+}
+
+// テストのみ実行 (デバッグ用)
+void MsTestOnly()
+{
+	g_start();
+	GetLine(NULL, 0);
+	g_stop();
+
+	_exit(0);
+}
+
+// ユーザーモードとして起動
+void MsUserMode(char *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon)
+{
+	wchar_t *title_w = CopyStrToUni(title);
+
+	MsUserModeW(title_w, start, stop, icon);
+
+	Free(title_w);
+}
+void MsUserModeW(wchar_t *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon)
+{
+	WNDCLASS wc;
+	HINSTANCE hDll;
+	HWND hWnd;
+	MSG msg;
+	INSTANCE *inst;
+	char title_a[MAX_PATH];
+	// 引数チェック
+	if (title == NULL || start == NULL || stop == NULL)
+	{
+		return;
+	}
+
+	UniToStr(title_a, sizeof(title_a), title);
+
+	is_usermode = true;
+	g_start = start;
+	g_stop = stop;
+
+	inst = NewSingleInstance(NULL);
+	if (inst == NULL)
+	{
+		if (service_for_9x_mode == false)
+		{
+			// Win9x サービスモードの場合はエラーを表示しない
+			MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_USERMODE_MUTEX"), ms->ExeFileNameW);
+		}
+		return;
+	}
+
+	if (Is64())
+	{
+		hDll = MsLoadLibraryAsDataFile(MsGetPenCoreDllFileName());
+	}
+	else
+	{
+		hDll = MsLoadLibrary(MsGetPenCoreDllFileName());
+	}
+
+	// アイコン読み込み
+	tray_icon = LoadImage(hDll, MAKEINTRESOURCE(icon), IMAGE_ICON, 16, 16,
+		(MsIsNt() ? LR_SHARED : 0) | LR_VGACOLOR);
+
+	// メインウインドウの作成
+	Zero(&wc, sizeof(wc));
+	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+	wc.hCursor = LoadCursor(NULL,IDC_ARROW);
+	wc.hIcon = LoadIcon(hDll, MAKEINTRESOURCE(icon));
+	wc.hInstance = ms->hInst;
+	wc.lpfnWndProc = MsUserModeWindowProc;
+	wc.lpszClassName = title_a;
+	if (RegisterClass(&wc) == 0)
+	{
+		return;
+	}
+
+	hWnd = CreateWindow(title_a, title_a, WS_OVERLAPPEDWINDOW,
+		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+		NULL, NULL, ms->hInst, NULL);
+
+	if (hWnd == NULL)
+	{
+		return;
+	}
+
+	hWndUsermode = hWnd;
+
+	wnd_end = false;
+	// ウインドウループ
+	while (wnd_end == false)
+	{
+		GetMessage(&msg, NULL, 0, 0);
+		TranslateMessage(&msg);
+		DispatchMessage(&msg);
+	}
+
+	FreeSingleInstance(inst);
+
+	hWndUsermode = NULL;
+
+	// 強制終了して良い
+	_exit(0);
+}
+
+// サービス停止処理メインスレッド
+void MsServiceStoperMainThread(THREAD *t, void *p)
+{
+	// 停止処理
+	g_stop();
+}
+
+// サービス停止処理用スレッド
+void MsServiceStoperThread(THREAD *t, void *p)
+{
+	THREAD *thread;
+	UINT64 selfkill_timeout = Tick64() + SVC_SELFKILL_TIMEOUT;
+
+	thread = NewThread(MsServiceStoperMainThread, NULL);
+
+	// まだ開始中の場合は開始スレッドの終了を待つ
+	while (WaitThread(starter_thread, 250) == false)
+	{
+		if (Tick64() >= selfkill_timeout)
+		{
+			// フリーズ時用の自殺
+			_exit(0);
+		}
+		// 開始処理が完了するまでの間、一定時間ごとに SetServiceStatus を呼び出す
+		status.dwWin32ExitCode = 0;
+		status.dwWaitHint = 100000;
+		status.dwCheckPoint++;
+		status.dwCurrentState = SERVICE_STOP_PENDING;
+		ms->nt->SetServiceStatus(ssh, &status);
+	}
+
+	ReleaseThread(starter_thread);
+	starter_thread = NULL;
+
+	while (WaitThread(thread, 250) == false)
+	{
+		if (Tick64() >= selfkill_timeout)
+		{
+			// フリーズ時用の自殺
+			_exit(0);
+		}
+		// 停止処理が完了するまでの間、一定時間ごとに SetServiceStatus を呼び出す
+		status.dwWin32ExitCode = 0;
+		status.dwWaitHint = 100000;
+		status.dwCheckPoint++;
+		status.dwCurrentState = SERVICE_STOP_PENDING;
+		ms->nt->SetServiceStatus(ssh, &status);
+	}
+
+	ReleaseThread(thread);
+
+	// 停止が完了したことを報告する
+	status.dwWin32ExitCode = 0;
+	status.dwWaitHint = 0;
+	status.dwCheckPoint = 0;
+	status.dwCurrentState = SERVICE_STOPPED;
+	ms->nt->SetServiceStatus(ssh, &status);
+
+	Set(server_stopped_event);
+}
+
+// サービスハンドラ
+void CALLBACK MsServiceHandler(DWORD opcode)
+{
+	switch (opcode)
+	{
+	case SERVICE_CONTROL_SHUTDOWN:
+	case SERVICE_CONTROL_STOP:
+		// 停止要求
+		status.dwWin32ExitCode = 0;
+		status.dwWaitHint = 100000;
+		status.dwCheckPoint = 0;
+		status.dwCurrentState = SERVICE_STOP_PENDING;
+
+		// 停止用スレッドを立てる
+		service_stopper_thread = NewThread(MsServiceStoperThread, NULL);
+		break;
+	}
+
+	ms->nt->SetServiceStatus(ssh, &status);
+}
+
+// サービス開始用スレッド
+void MsServiceStarterMainThread(THREAD *t, void *p)
+{
+	// 開始
+	g_start();
+}
+
+// サービスのディスパッチ関数
+void CALLBACK MsServiceDispatcher(DWORD argc, LPTSTR *argv)
+{
+	// サービスの準備
+	Zero(&status, sizeof(status));
+	status.dwServiceType = SERVICE_WIN32;
+	status.dwCurrentState = SERVICE_START_PENDING;
+	status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
+
+	ssh = ms->nt->RegisterServiceCtrlHandler(g_service_name, MsServiceHandler);
+
+	if (ssh == NULL)
+	{
+		Alert("RegisterServiceCtrlHandler() Failed.", "MsServiceDispatcher()");
+		return;
+	}
+
+	status.dwWaitHint = 10000;
+	status.dwCheckPoint = 0;
+	status.dwCurrentState = SERVICE_START_PENDING;
+	ms->nt->SetServiceStatus(ssh, &status);
+
+	// サービス開始用スレッドを作成する
+	starter_thread = NewThread(MsServiceStarterMainThread, NULL);
+
+	// 開始完了を報告する
+	status.dwWaitHint = 0;
+	status.dwCheckPoint = 0;
+	status.dwCurrentState = SERVICE_RUNNING;
+	ms->nt->SetServiceStatus(ssh, &status);
+}
+
+// サービスとして動作
+void MsServiceMode(SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)
+{
+	SERVICE_TABLE_ENTRY dispatch_table[] =
+	{
+		{"", MsServiceDispatcher},
+		{NULL, NULL},
+	};
+	INSTANCE *inst;
+	// 引数チェック
+	if (start == NULL || stop == NULL)
+	{
+		return;
+	}
+
+	MsSetErrorModeToSilent();
+
+	g_start = start;
+	g_stop = stop;
+
+	server_stopped_event = NewEvent();
+
+	inst = NewSingleInstance(NULL);
+	if (inst == NULL)
+	{
+		MsgBoxEx(NULL, MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION,
+			_UU("SVC_SERVICE_MUTEX"), g_service_name, ms->ExeFileNameW);
+		return;
+	}
+
+	// サービス設定を更新する
+	MsUpdateServiceConfig(g_service_name);
+
+	if (ms->nt->StartServiceCtrlDispatcher(dispatch_table) == false)
+	{
+		Alert("StartServiceCtrlDispatcher() Failed.", "MsServiceMode()");
+		return;
+	}
+
+	MsUpdateServiceConfig(g_service_name);
+
+	FreeSingleInstance(inst);
+
+	// サービス終了後は直ちにプロセスを終了する
+	Wait(server_stopped_event, INFINITE);
+	ReleaseEvent(server_stopped_event);
+	WaitThread(service_stopper_thread, INFINITE);
+	ReleaseThread(service_stopper_thread);
+	server_stopped_event = NULL;
+
+	_exit(0);
+}
+
+// テストモードとして起動
+void MsTestMode(char *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)
+{
+	wchar_t *title_w = CopyStrToUni(title);
+
+	MsTestModeW(title_w, start, stop);
+	Free(title_w);
+}
+void MsTestModeW(wchar_t *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)
+{
+	INSTANCE *inst;
+	// 引数チェック
+	if (title == NULL || start == NULL || stop == NULL)
+	{
+		return;
+	}
+
+	is_usermode = true;
+
+	inst = NewSingleInstance(NULL);
+	if (inst == NULL)
+	{
+		// すでに起動している
+		MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_TEST_MUTEX"), ms->ExeFileNameW);
+		return;
+	}
+
+	// 起動
+	start();
+
+	// メッセージ表示
+	MsgBoxEx(NULL, MB_ICONINFORMATION | MB_SYSTEMMODAL, _UU("SVC_TEST_MSG"), title);
+
+	// 停止
+	stop();
+
+	FreeSingleInstance(inst);
+}
+
+// サービスマネージャを呼び出し中のプロセスのプロセス ID を書き込む
+void MsWriteCallingServiceManagerProcessId(char *svcname, UINT pid)
+{
+	char tmp[MAX_PATH];
+
+	Format(tmp, sizeof(tmp), SVC_CALLING_SM_PROCESS_ID_KEY, svcname);
+
+	if (pid != 0)
+	{
+		MsRegWriteInt(REG_LOCAL_MACHINE, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE, pid);
+		MsRegWriteInt(REG_CURRENT_USER, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE, pid);
+	}
+	else
+	{
+		MsRegDeleteValue(REG_LOCAL_MACHINE, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE);
+		MsRegDeleteKey(REG_LOCAL_MACHINE, tmp);
+
+		MsRegDeleteValue(REG_CURRENT_USER, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE);
+		MsRegDeleteKey(REG_CURRENT_USER, tmp);
+	}
+}
+
+// サービスマネージャを呼び出し中のプロセス ID を取得する
+UINT MsReadCallingServiceManagerProcessId(char *svcname, bool current_user)
+{
+	char tmp[MAX_PATH];
+	// 引数チェック
+	if (svcname == NULL)
+	{
+		return 0;
+	}
+
+	Format(tmp, sizeof(tmp), SVC_CALLING_SM_PROCESS_ID_KEY, svcname);
+
+	return MsRegReadInt(current_user ? REG_CURRENT_USER : REG_LOCAL_MACHINE, tmp, SVC_CALLING_SM_PROCESS_ID_VALUE);
+}
+
+// サービスメイン関数
+UINT MsService(char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon)
+{
+	UINT mode;
+	UINT ret = 0;
+	char *arg;
+	wchar_t *arg_w;
+	TOKEN_LIST *t = NULL;
+	UNI_TOKEN_LIST *ut = NULL;
+	char *service_name;
+	wchar_t *service_title;
+	wchar_t *service_description;
+	wchar_t *service_title_uni;
+	char tmp[MAX_SIZE];
+	bool restoreReg = false;
+	bool silent = false;
+	// 引数チェック
+	if (name == NULL || start == NULL || stop == NULL)
+	{
+		return ret;
+	}
+
+	// Mayaqua の開始
+	InitMayaqua(false, false, 0, NULL);
+
+	// MS-IME の停止
+	MsDisableIme();
+
+	// サービスに関する情報を string table から取得
+	Format(tmp, sizeof(tmp), SVC_NAME, name);
+	service_name = _SS(tmp);
+	Format(tmp, sizeof(tmp), SVC_TITLE, name);
+	service_title = _UU(tmp);
+	service_title_uni = _UU(tmp);
+	Format(tmp, sizeof(tmp), SVC_DESCRIPT, name);
+	service_description = _UU(tmp);
+
+	if (StrLen(service_name) == 0 || UniStrLen(service_title) == 0)
+	{
+		// サービス情報が見つからない
+		MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_NOT_FOUND"), name);
+	}
+	else
+	{
+		wchar_t path[MAX_SIZE];
+		// 引数のチェック
+		mode = SVC_MODE_NONE;
+
+		t = GetCommandLineToken();
+		arg = NULL;
+
+		ut = GetCommandLineUniToken();
+		arg_w = NULL;
+
+		if (t->NumTokens >= 1)
+		{
+			arg = t->Token[0];
+		}
+		if(t->NumTokens >= 2)
+		{
+			if(StrCmpi(t->Token[1], SVC_ARG_SILENT) == 0)
+			{
+				silent = true;
+			}
+		}
+
+		if (ut->NumTokens >= 1)
+		{
+			arg_w = ut->Token[0];
+		}
+
+		if (arg != NULL)
+		{
+			if (StrCmpi(arg, SVC_ARG_INSTALL) == 0)
+			{
+				mode = SVC_MODE_INSTALL;
+			}
+			if (StrCmpi(arg, SVC_ARG_UNINSTALL) == 0)
+			{
+				mode = SVC_MODE_UNINSTALL;
+			}
+			if (StrCmpi(arg, SVC_ARG_START) == 0)
+			{
+				mode = SVC_MODE_START;
+			}
+			if (StrCmpi(arg, SVC_ARG_STOP) == 0)
+			{
+				mode = SVC_MODE_STOP;
+			}
+			if (StrCmpi(arg, SVC_ARG_TEST) == 0)
+			{
+				mode = SVC_MODE_TEST;
+			}
+			if (StrCmpi(arg, SVC_ARG_USERMODE) == 0)
+			{
+				mode = SVC_MODE_USERMODE;
+			}
+			if (StrCmpi(arg, SVC_ARG_SETUP_INSTALL) == 0)
+			{
+				mode = SVC_MODE_SETUP_INSTALL;
+			}
+			if (StrCmpi(arg, SVC_ARG_SETUP_UNINSTALL) == 0)
+			{
+				mode = SVC_MODE_SETUP_UNINSTALL;
+			}
+			if (StrCmpi(arg, SVC_ARG_WIN9X_SERVICE) == 0)
+			{
+				mode = SVC_MODE_WIN9X_SERVICE;
+			}
+			if (StrCmpi(arg, SVC_ARG_WIN9X_INSTALL) == 0)
+			{
+				mode = SVC_MODE_WIN9X_INSTALL;
+			}
+			if (StrCmpi(arg, SVC_ARG_WIN9X_UNINSTALL) == 0)
+			{
+				mode = SVC_MODE_WIN9X_UNINSTALL;
+			}
+			if (StrCmpi(arg, SVC_ARG_TCP) == 0)
+			{
+				mode = SVC_MODE_TCP;
+			}
+			if (StrCmpi(arg, SVC_ARG_TCP_SETUP) == 0)
+			{
+				mode = SVC_MODE_TCPSETUP;
+			}
+			if (StrCmpi(arg, SVC_ARG_TRAFFIC) == 0)
+			{
+				mode = SVC_MODE_TRAFFIC;
+			}
+			if (StrCmpi(arg, SVC_ARG_UIHELP) == 0)
+			{
+				mode = SVC_MODE_UIHELP;
+			}
+			if (StrCmpi(arg, SVC_ARG_USERMODE_SHOWTRAY) == 0)
+			{
+				char tmp[MAX_SIZE];
+				mode = SVC_MODE_USERMODE;
+				Format(tmp, sizeof(tmp), SVC_HIDETRAY_REG_VALUE, service_title);
+				MsRegDeleteValue(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, tmp);
+			}
+			if (StrCmpi(arg, SVC_ARG_USERMODE_HIDETRAY) == 0)
+			{
+				char tmp[MAX_SIZE];
+				mode = SVC_MODE_USERMODE;
+				Format(tmp, sizeof(tmp), SVC_HIDETRAY_REG_VALUE, service_title);
+				MsRegWriteInt(REG_CURRENT_USER, SVC_USERMODE_SETTING_KEY, tmp, 1);
+			}
+			if (StrCmpi(arg, SVC_ARG_SERVICE) == 0)
+			{
+				mode = SVC_MODE_SERVICE;
+			}
+
+			if (mode != SVC_MODE_NONE)
+			{
+				// Network Config
+				MsInitGlobalNetworkConfig();
+			}
+		}
+
+		// サービスとして実行する際のコマンドライン名を取得する
+		UniFormat(path, sizeof(path), SVC_RUN_COMMANDLINE, ms->ExeFileNameW);
+
+		if ((mode == SVC_MODE_INSTALL || mode == SVC_MODE_UNINSTALL || mode == SVC_MODE_START ||
+			mode == SVC_MODE_STOP || mode == SVC_MODE_SERVICE) &&
+			(ms->IsNt == false))
+		{
+			// Windows NT 以外で NT 系のコマンドを使用しようとした
+			MsgBox(NULL, MB_ICONSTOP, _UU("SVC_NT_ONLY"));
+		}
+		else if ((mode == SVC_MODE_INSTALL || mode == SVC_MODE_UNINSTALL || mode == SVC_MODE_START ||
+			mode == SVC_MODE_STOP || mode == SVC_MODE_SERVICE) &&
+			(ms->IsAdmin == false))
+		{
+			// Administrators 権限が無い
+			MsgBox(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_ADMIN"));
+		}
+		else
+		{
+			// モードごとに処理を行う
+			switch (mode)
+			{
+			case SVC_MODE_NONE:
+				// 案内メッセージを表示して終了する
+				if (arg_w != NULL && UniEndWith(arg_w, L".uvpn"))
+				{
+					if (MsgBox(NULL, MB_ICONQUESTION | MB_YESNO, _UU("CM_VPN_FILE_CLICKED")) == IDYES)
+					{
+						wchar_t vpncmgr[MAX_PATH];
+						wchar_t filename[MAX_PATH];
+
+						UniFormat(filename, sizeof(filename), L"\"%s\"", arg_w);
+
+						if (Is64() == false)
+						{
+							UniFormat(vpncmgr, sizeof(vpncmgr), L"%s\\utvpncmgr.exe", MsGetExeDirNameW());
+						}
+						else
+						{
+							UniFormat(vpncmgr, sizeof(vpncmgr), L"%s\\utvpncmgr_x64.exe", MsGetExeDirNameW());
+						}
+
+						RunW(vpncmgr, filename, false, false);
+					}
+				}
+				else
+				{
+					MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_HELP"),
+						service_title, service_name, service_title, service_title, service_name, service_title, service_name, service_title, service_name, service_title, service_name, service_title, service_title);
+				}
+				break;
+
+			case SVC_MODE_SETUP_INSTALL:
+				// setup.exe インストール モード
+				// 古いものをアンインストールする
+				MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
+				restoreReg = true;
+
+				if (MsIsServiceInstalled(service_name))
+				{
+					if (MsIsServiceRunning(service_name))
+					{
+						MsStopService(service_name);
+					}
+					MsUninstallService(service_name);
+				}
+				if (MsInstallServiceW(service_name, service_title, service_description, path) == false)
+				{
+					ret = 1;
+				}
+				MsStartService(service_name);
+				MsWriteCallingServiceManagerProcessId(service_name, 0);
+				break;
+
+			case SVC_MODE_SETUP_UNINSTALL:
+				// setup.exe アンインストール モード
+				MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
+				restoreReg = true;
+
+				if (MsIsServiceInstalled(service_name))
+				{
+					if (MsIsServiceRunning(service_name))
+					{
+						MsStopService(service_name);
+					}
+					if (MsUninstallService(service_name) == false)
+					{
+						ret = 1;
+					}
+				}
+				break;
+
+			case SVC_MODE_INSTALL:
+				// サービスのインストール
+				// すでにインストールされているかどうか確認する
+				MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
+				restoreReg = true;
+
+				if (MsIsServiceInstalled(service_name))
+				{
+					// すでにインストールされている
+					// アンインストールするかどうか確認のメッセージを表示する
+					if (silent == false)
+					{
+						if (MsgBoxEx(NULL, MB_ICONQUESTION | MB_YESNO | MB_DEFBUTTON2, _UU("SVC_ALREADY_INSTALLED"),
+							service_title, service_name) == IDNO)
+						{
+							// 処理をキャンセルする
+							break;
+						}
+					}
+					// 既存のサービスが動作しているか?
+					if (MsIsServiceRunning(service_name))
+					{
+						// 停止を試みる
+						if (MsStopService(service_name) == false)
+						{
+							// 停止に失敗した
+							MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_STOP_FAILED"),
+								service_title, service_name);
+							break;
+						}
+					}
+					// アンインストールする
+					if (MsUninstallService(service_name) == false)
+					{
+						// アンインストールに失敗した
+						MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_UNINSTALL_FAILED"),
+							service_title, service_name);
+						break;
+					}
+				}
+
+				// インストールを行う
+				if (MsInstallServiceW(service_name, service_title, service_description, path) == false)
+				{
+					// インストールに失敗した
+					MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_INSTALL_FAILED"),
+						service_title, service_name);
+					break;
+				}
+
+				// サービスを開始する
+				if (MsStartService(service_name) == false)
+				{
+					// 開始に失敗した
+					MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_INSTALL_FAILED_2"),
+						service_title, service_name, path);
+					break;
+				}
+
+				// すべて成功した
+				if(silent == false)
+				{
+					MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_INSTALL_OK"),
+						service_title, service_name, path);
+				}
+				break;
+
+			case SVC_MODE_UNINSTALL:
+				// サービスのアンインストール
+				// すでにインストールされているかどうか確認する
+				MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
+				restoreReg = true;
+
+				if (MsIsServiceInstalled(service_name) == false)
+				{
+					if(silent == false)
+					{
+						MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_INSTALLED"),
+							service_title, service_name, path);
+					}
+					break;
+				}
+
+				// サービスが起動中の場合は停止する
+				if (MsIsServiceRunning(service_name))
+				{
+					// サービスを停止する
+					if (MsStopService(service_name) == false)
+					{
+						// 停止に失敗した
+						MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_STOP_FAILED"),
+							service_title, service_name);
+						break;
+					}
+				}
+
+				// サービスをアンインストールする
+				if (MsUninstallService(service_name) == false)
+				{
+					MsgBoxEx(NULL, MB_ICONSTOP, _UU("SVC_UNINSTALL_FAILED"),
+						service_title, service_name);
+					break;
+				}
+
+				// すべて成功した
+				if(silent == false)
+				{
+					MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_UNINSTALL_OK"),
+						service_title, service_name);
+				}
+				break;
+
+			case SVC_MODE_START:
+				// サービスの開始
+				MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
+				restoreReg = true;
+
+				if (MsIsServiceInstalled(service_name) == false)
+				{
+					// サービスはインストールされていない
+					MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_INSTALLED"),
+						service_title, service_name);
+					break;
+				}
+
+				// サービスが起動中かどうか確認する
+				if (MsIsServiceRunning(service_name))
+				{
+					// サービスが起動中
+					if(silent == false)
+					{
+						MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVR_ALREADY_START"),
+							service_title, service_name);
+					}
+					break;
+				}
+
+				// サービスを起動する
+				if (MsStartService(service_name) == false)
+				{
+					// 開始に失敗した
+					MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_START_FAILED"),
+						service_title, service_name);
+					break;
+				}
+
+				// すべて成功した
+				if(silent == false)
+				{
+					MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_START_OK"),
+						service_title, service_name);
+				}
+				break;
+
+			case SVC_MODE_STOP:
+				// サービスの停止
+				MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
+				restoreReg = true;
+
+				if (MsIsServiceInstalled(service_name) == false)
+				{
+					// サービスはインストールされていない
+					if(silent == false)
+					{
+						MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_NOT_INSTALLED"),
+							service_title, service_name);
+					}
+					break;
+				}
+
+				// サービスが起動中かどうか確認する
+				if (MsIsServiceRunning(service_name) == false)
+				{
+					// サービスが停止中
+					if(silent == false)
+					{
+						MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_ALREADY_STOP"),
+							service_title, service_name);
+					}
+					break;
+				}
+				// サービスを停止する
+				if (MsStopService(service_name) == false)
+				{
+					// 停止に失敗した
+					MsgBoxEx(NULL, MB_ICONEXCLAMATION, _UU("SVC_STOP_FAILED"),
+						service_title, service_name);
+					break;
+				}
+
+				// すべて成功した
+				if(silent == false)
+				{
+					MsgBoxEx(NULL, MB_ICONINFORMATION, _UU("SVC_STOP_OK"),
+						service_title, service_name);
+				}
+				break;
+
+			case SVC_MODE_TEST:
+				// テストモード
+				MsTestModeW(service_title, start, stop);
+				break;
+
+			case SVC_MODE_WIN9X_SERVICE:
+				// Win9x サービスモード
+				// (タスクトレイのアイコンを無条件で非表示にする)
+				if (MsIsNt())
+				{
+					// Windows 2000 以降では動作させない
+					break;
+				}
+				service_for_9x_mode = true;
+			case SVC_MODE_USERMODE:
+				// ユーザーモード
+				MsUserModeW(service_title, start, stop, icon);
+				break;
+
+			case SVC_MODE_WIN9X_INSTALL:
+				// Win9x インストールモード
+				MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
+				restoreReg = true;
+
+				if (MsIsNt() == false)
+				{
+					// レジストリキーの追加
+					char cmdline[MAX_PATH];
+					Format(cmdline, sizeof(cmdline), "\"%s\" %s",
+						MsGetExeFileName(), SVC_ARG_WIN9X_SERVICE);
+					MsRegWriteStr(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_1,
+						name, cmdline);
+					MsRegWriteStr(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_2,
+						name, cmdline);
+
+					// 実行
+					Run(MsGetExeFileName(), SVC_ARG_WIN9X_SERVICE, false, false);
+				}
+				break;
+
+			case SVC_MODE_WIN9X_UNINSTALL:
+				// Win9x アンインストールモード
+				MsWriteCallingServiceManagerProcessId(service_name, MsGetCurrentProcessId());
+				restoreReg = true;
+
+				if (MsIsNt() == false)
+				{
+					// レジストリキーの削除
+					MsRegDeleteValue(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_1,
+						name);
+					MsRegDeleteValue(REG_LOCAL_MACHINE, WIN9X_SVC_REGKEY_2,
+						name);
+
+					// 自分以外のすべてのプロセスを終了
+					MsKillOtherInstance();
+				}
+				break;
+
+			case SVC_MODE_SERVICE:
+				// サービスとして動作
+				StrCpy(g_service_name, sizeof(g_service_name), service_name);
+				MsServiceMode(start, stop);
+				break;
+
+			case SVC_MODE_TCP:
+				// TCP ユーティリティ
+				InitCedar();
+				InitWinUi(service_title_uni, NULL, 0);
+				ShowTcpIpConfigUtil(NULL, true);
+				FreeWinUi();
+				FreeCedar();
+				break;
+
+			case SVC_MODE_TCPSETUP:
+				// TCP 最適化モード (インストーラから呼ばれる)
+				InitCedar();
+				InitWinUi(service_title_uni, NULL, 0);
+				ShowTcpIpConfigUtil(NULL, false);
+				FreeWinUi();
+				FreeCedar();
+				break;
+
+			case SVC_MODE_TRAFFIC:
+				// 通信スループット測定ツール
+				InitCedar();
+				InitWinUi(service_title_uni, NULL, 0);
+				CmTraffic(NULL);
+				FreeWinUi();
+				FreeCedar();
+				break;
+
+			case SVC_MODE_UIHELP:
+				// UI Helper の起動
+				CnStart();
+				break;
+			}
+
+		}
+		FreeToken(t);
+		UniFreeToken(ut);
+
+		if (restoreReg)
+		{
+			MsWriteCallingServiceManagerProcessId(service_name, 0);
+		}
+	}
+
+	FreeMayaqua();
+
+	return 0;
+}
+
+// 指定したセッションのユーザー名を取得する
+wchar_t *MsGetSessionUserName(UINT session_id)
+{
+	if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())
+	{
+		wchar_t *ret;
+		wchar_t *name;
+		UINT size = 0;
+		if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id,
+			WTSUserName, (wchar_t *)&name, &size) == false)
+		{
+			return NULL;
+		}
+
+		if (name == NULL || UniStrLen(name) == 0)
+		{
+			ret = NULL;
+		}
+		else
+		{
+			ret = UniCopyStr(name);
+		}
+
+		ms->nt->WTSFreeMemory(name);
+
+		return ret;
+	}
+	return NULL;
+}
+
+// 現在のデスクトップが VNC で利用可能かどうか取得する
+bool MsIsCurrentDesktopAvailableForVnc()
+{
+	if (MsIsNt() == false)
+	{
+		return true;
+	}
+
+	if (MsIsCurrentTerminalSessionActive() == false)
+	{
+		return false;
+	}
+
+	if (ms->nt->OpenDesktopA == NULL ||
+		ms->nt->CloseDesktop == NULL ||
+		ms->nt->SwitchDesktop == NULL)
+	{
+		return true;
+	}
+	else
+	{
+		HDESK hDesk = ms->nt->OpenDesktopA("default", 0, false, DESKTOP_SWITCHDESKTOP);
+		bool ret;
+
+		if (hDesk == NULL)
+		{
+			return false;
+		}
+
+		ret = ms->nt->SwitchDesktop(hDesk);
+		ms->nt->CloseDesktop(hDesk);
+
+		return ret;
+	}
+}
+
+// 現在のターミナルセッションがアクティブかどうか取得する
+bool MsIsCurrentTerminalSessionActive()
+{
+	return MsIsTerminalSessionActive(MsGetCurrentTerminalSessionId());
+}
+
+// 指定したターミナルセッションがアクティブかどうか取得する
+bool MsIsTerminalSessionActive(UINT session_id)
+{
+	if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())
+	{
+		UINT *status = NULL;
+		UINT size = sizeof(status);
+		bool active = true;
+
+		if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_id,
+			WTSConnectState, (wchar_t *)&status, &size) == false)
+		{
+			return true;
+		}
+
+		switch (*status)
+		{
+		case WTSDisconnected:
+		case WTSShadow:
+		case WTSIdle:
+		case WTSDown:
+		case WTSReset:
+			active = false;
+			break;
+		}
+
+		ms->nt->WTSFreeMemory(status);
+
+		return active;
+	}
+
+	return true;
+}
+
+// 現在のターミナルセッション ID を取得する
+UINT MsGetCurrentTerminalSessionId()
+{
+	if (MsIsTerminalServiceInstalled() || MsIsUserSwitchingInstalled())
+	{
+		UINT ret;
+		UINT *session_id = NULL;
+		UINT size = sizeof(session_id);
+		if (ms->nt->WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION,
+			WTSSessionId, (wchar_t *)&session_id, &size) == false)
+		{
+			return 0;
+		}
+
+		ret = *session_id;
+
+		ms->nt->WTSFreeMemory(session_id);
+
+		return ret;
+	}
+
+	return 0;
+}
+
+// ターミナルサービスがインストールされていて複数セッションがログイン可能かどうか調べる
+bool MsIsTerminalServiceMultiUserInstalled()
+{
+	OS_INFO *info = GetOsInfo();
+	OSVERSIONINFOEX i;
+	if (MsIsTerminalServiceInstalled() == false)
+	{
+		return false;
+	}
+
+	if (OS_IS_SERVER(info->OsType) == false)
+	{
+		return false;
+	}
+
+	Zero(&i, sizeof(i));
+	i.dwOSVersionInfoSize = sizeof(i);
+	if (GetVersionEx((OSVERSIONINFO *)&i) == false)
+	{
+		return false;
+	}
+
+	if (i.wSuiteMask & VER_SUITE_SINGLEUSERTS)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ユーザー切り替えがインストールされているかどうか調べる
+bool MsIsUserSwitchingInstalled()
+{
+	OS_INFO *info = GetOsInfo();
+	OSVERSIONINFOEX i;
+
+	if (OS_IS_WINDOWS_NT(info->OsType) == false)
+	{
+		return false;
+	}
+
+	if (ms->nt->WTSDisconnectSession == NULL ||
+		ms->nt->WTSFreeMemory == NULL ||
+		ms->nt->WTSQuerySessionInformation == NULL)
+	{
+		return false;
+	}
+
+	if (GET_KETA(info->OsType, 100) < 2)
+	{
+		return false;
+	}
+
+	Zero(&i, sizeof(i));
+	i.dwOSVersionInfoSize = sizeof(i);
+	if (GetVersionEx((OSVERSIONINFO *)&i) == false)
+	{
+		return false;
+	}
+
+	if (i.wSuiteMask & VER_SUITE_SINGLEUSERTS)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// リモートデスクトップを有効にする
+bool MsEnableRemoteDesktop()
+{
+	OS_INFO *info = GetOsInfo();
+
+	if (MsIsRemoteDesktopAvailable() == false)
+	{
+		return false;
+	}
+
+	if (MsIsRemoteDesktopEnabled())
+	{
+		return true;
+	}
+
+	if (GET_KETA(info->OsType, 100) == 2)
+	{
+		// Windows 2000
+		return false;
+	}
+
+	if (MsRegWriteInt(REG_LOCAL_MACHINE,
+		"SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
+		"fDenyTSConnections", 0) == false)
+	{
+		return false;
+	}
+
+	if (MsIsVista())
+	{
+		if (MsRegWriteInt(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp",
+			"UserAuthentication", 0) == false)
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// リモートデスクトップが有効かどうか調べる
+bool MsIsRemoteDesktopEnabled()
+{
+	OS_INFO *info = GetOsInfo();
+
+	if (MsIsRemoteDesktopAvailable() == false)
+	{
+		return false;
+	}
+
+	if (GET_KETA(info->OsType, 100) == 2)
+	{
+		// Windows 2000
+		return MsIsServiceRunning("TermService");
+	}
+	else
+	{
+		// Windows XP 以降
+		bool b = MsRegReadInt(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
+			"fDenyTSConnections");
+
+		if (MsIsVista() == false)
+		{
+			return b ? false : true;
+		}
+		else
+		{
+			if (b)
+			{
+				return false;
+			}
+			else
+			{
+				if (MsRegReadInt(REG_LOCAL_MACHINE,
+					"SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp",
+					"UserAuthentication"))
+				{
+					return false;
+				}
+				else
+				{
+					return true;
+				}
+			}
+		}
+	}
+}
+
+// レジストリ操作によってリモートデスクトップが利用可能になるかどうか調べる
+bool MsIsRemoteDesktopCanEnableByRegistory()
+{
+	OS_INFO *info = GetOsInfo();
+	if (MsIsRemoteDesktopAvailable() == false)
+	{
+		return false;
+	}
+
+	if (GET_KETA(info->OsType, 100) == 2)
+	{
+		// Windows 2000
+		return false;
+	}
+	else
+	{
+		// それ以外
+		return true;
+	}
+}
+
+// Windows 2000 かどうか調べる
+bool MsIsWin2000()
+{
+	OS_INFO *info = GetOsInfo();
+
+	if (OS_IS_WINDOWS_NT(info->OsType) == false)
+	{
+		return false;
+	}
+
+	if (GET_KETA(info->OsType, 100) == 2)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// Windows 2000 以降かどうか調べる
+bool MsIsWin2000OrGreater()
+{
+	OS_INFO *info = GetOsInfo();
+
+	if (OS_IS_WINDOWS_NT(info->OsType) == false)
+	{
+		return false;
+	}
+
+	if (GET_KETA(info->OsType, 100) >= 2)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// リモートデスクトップが利用可能かどうか調べる
+bool MsIsRemoteDesktopAvailable()
+{
+	OS_INFO *info = GetOsInfo();
+	if (MsIsTerminalServiceInstalled() == false)
+	{
+		return false;
+	}
+
+	if (GET_KETA(info->OsType, 100) == 2)
+	{
+		// Windows 2000
+		if (info->OsType == 2200)
+		{
+			// Windows 2000 Professional
+			return false;
+		}
+		else
+		{
+			// Windows 2000 サーバー系
+			return true;
+		}
+	}
+	else if (GET_KETA(info->OsType, 100) == 3)
+	{
+		// Windows XP
+		if (info->OsType == OSTYPE_WINDOWS_XP_HOME)
+		{
+			// Home Edition
+			return false;
+		}
+		else
+		{
+			// Professional Edition
+			return true;
+		}
+	}
+	else if (GET_KETA(info->OsType, 100) == 4)
+	{
+		// Windows Server 2003
+		return true;
+	}
+	else if (GET_KETA(info->OsType, 100) >= 5)
+	{
+		// Windows Vista 以降
+		OSVERSIONINFOEX i;
+
+		Zero(&i, sizeof(i));
+		i.dwOSVersionInfoSize = sizeof(i);
+		if (GetVersionEx((OSVERSIONINFO *)&i) == false)
+		{
+			return false;
+		}
+
+		if (i.wSuiteMask & VER_SUITE_PERSONAL)
+		{
+			// Home 系
+			return false;
+		}
+		else
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// ターミナルサービスがインストールされているかどうか調べる
+bool MsIsTerminalServiceInstalled()
+{
+	OS_INFO *info = GetOsInfo();
+	OSVERSIONINFOEX i;
+
+	if (OS_IS_WINDOWS_NT(info->OsType) == false)
+	{
+		return false;
+	}
+
+	if (ms->nt->WTSDisconnectSession == NULL ||
+		ms->nt->WTSFreeMemory == NULL ||
+		ms->nt->WTSQuerySessionInformation == NULL)
+	{
+		return false;
+	}
+
+	if (GET_KETA(info->OsType, 100) < 2)
+	{
+		return false;
+	}
+
+	Zero(&i, sizeof(i));
+	i.dwOSVersionInfoSize = sizeof(i);
+	if (GetVersionEx((OSVERSIONINFO *)&i) == false)
+	{
+		return false;
+	}
+
+	if (i.wSuiteMask & VER_SUITE_TERMINAL || i.wSuiteMask & VER_SUITE_SINGLEUSERTS)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// サービスを停止する
+bool MsStopService(char *name)
+{
+	SC_HANDLE sc, service;
+	bool ret = false;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+	if (ms->IsNt == false)
+	{
+		return false;
+	}
+
+	sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+	if (sc == NULL)
+	{
+		return false;
+	}
+
+	service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);
+	if (service != NULL)
+	{
+		SERVICE_STATUS st;
+		ret = ms->nt->ControlService(service, SERVICE_CONTROL_STOP, &st);
+
+		ms->nt->CloseServiceHandle(service);
+	}
+
+	if (ret)
+	{
+		UINT64 end = Tick64() + 10000ULL;
+		while (Tick64() < end)
+		{
+			if (MsIsServiceRunning(name) == false)
+			{
+				break;
+			}
+
+			SleepThread(250);
+		}
+	}
+
+	ms->nt->CloseServiceHandle(sc);
+	return ret;
+}
+
+// サービスを起動する
+bool MsStartService(char *name)
+{
+	return MsStartServiceEx(name, NULL);
+}
+bool MsStartServiceEx(char *name, UINT *error_code)
+{
+	SC_HANDLE sc, service;
+	bool ret = false;
+	static UINT dummy = 0;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+	if (ms->IsNt == false)
+	{
+		return false;
+	}
+	if (error_code == NULL)
+	{
+		error_code = &dummy;
+	}
+
+	*error_code = 0;
+
+	sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+	if (sc == NULL)
+	{
+		*error_code = GetLastError();
+		return false;
+	}
+
+	service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);
+	if (service != NULL)
+	{
+		ret = ms->nt->StartService(service, 0, NULL);
+
+		ms->nt->CloseServiceHandle(service);
+	}
+	else
+	{
+		*error_code = GetLastError();
+	}
+
+	if (ret)
+	{
+		UINT64 end = Tick64() + 10000ULL;
+		while (Tick64() < end)
+		{
+			if (MsIsServiceRunning(name))
+			{
+				break;
+			}
+
+			SleepThread(250);
+		}
+	}
+
+	ms->nt->CloseServiceHandle(sc);
+	return ret;
+}
+
+// サービスが起動しているかどうか取得する
+bool MsIsServiceRunning(char *name)
+{
+	SC_HANDLE sc, service;
+	bool ret = false;
+	// 引数チェック
+	if (name == NULL || IsEmptyStr(name))
+	{
+		return false;
+	}
+	if (ms->IsNt == false)
+	{
+		return false;
+	}
+
+	sc = ms->nt->OpenSCManager(NULL, NULL, GENERIC_READ);
+	if (sc == NULL)
+	{
+		return false;
+	}
+
+	service = ms->nt->OpenService(sc, name, GENERIC_READ);
+	if (service != NULL)
+	{
+		SERVICE_STATUS st;
+		Zero(&st, sizeof(st));
+		if (ms->nt->QueryServiceStatus(service, &st))
+		{
+			switch (st.dwCurrentState)
+			{
+			case SERVICE_CONTINUE_PENDING:
+			case SERVICE_PAUSE_PENDING:
+			case SERVICE_PAUSED:
+			case SERVICE_RUNNING:
+			case SERVICE_START_PENDING:
+			case SERVICE_STOP_PENDING:
+				ret = true;
+				break;
+			}
+		}
+
+		ms->nt->CloseServiceHandle(service);
+	}
+
+	ms->nt->CloseServiceHandle(sc);
+	return ret;
+}
+
+// サービスをアンインストールする
+bool MsUninstallService(char *name)
+{
+	SC_HANDLE sc, service;
+	bool ret = false;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+	if (ms->IsNt == false)
+	{
+		return false;
+	}
+
+	MsStopService(name);
+
+	sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+	if (sc == NULL)
+	{
+		return false;
+	}
+
+	service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);
+	if (service != NULL)
+	{
+		if (ms->nt->DeleteService(service))
+		{
+			ret = true;
+		}
+		ms->nt->CloseServiceHandle(service);
+	}
+
+	ms->nt->CloseServiceHandle(sc);
+
+	if (ret)
+	{
+		SleepThread(2000);
+	}
+
+	return ret;
+}
+
+// サービス設定を更新する
+bool MsUpdateServiceConfig(char *name)
+{
+	SC_HANDLE sc, service;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	// Windows 起動直後かどうか (デッドロック防止)
+	if (timeGetTime() <= (60 * 30 * 1000))
+	{
+		if (MsRegReadInt(REG_LOCAL_MACHINE, "Software\\SoftEther Corporation\\Update Service Config", name) != 0)
+		{
+			return false;
+		}
+	}
+
+	sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+	if (sc == NULL)
+	{
+		return false;
+	}
+
+	service = ms->nt->OpenService(sc, name, SERVICE_ALL_ACCESS);
+	if (service != NULL)
+	{
+		if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
+		{
+			SERVICE_FAILURE_ACTIONS action;
+			SC_ACTION *e;
+			Zero(&action, sizeof(action));
+			e = ZeroMalloc(sizeof(SC_ACTION) * 3);
+			e[0].Delay = 10000; e[0].Type = SC_ACTION_RESTART;
+			e[1].Delay = 10000; e[1].Type = SC_ACTION_RESTART;
+			e[2].Delay = 10000; e[2].Type = SC_ACTION_RESTART;
+			action.cActions = 3;
+			action.lpsaActions = e;
+			action.dwResetPeriod = 1 * 60 * 60 * 24;
+			ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS, &action);
+
+			MsRegWriteInt(REG_LOCAL_MACHINE, "Software\\SoftEther Corporation\\Update Service Config", name, 1);
+		}
+		ms->nt->CloseServiceHandle(service);
+	}
+
+	ms->nt->CloseServiceHandle(sc);
+
+	return true;
+}
+
+// サービスをインストールする
+bool MsInstallService(char *name, char *title, wchar_t *description, char *path)
+{
+	wchar_t title_w[MAX_PATH];
+	wchar_t path_w[MAX_PATH];
+	// 引数チェック
+	if (name == NULL || title == NULL || path == NULL)
+	{
+		return false;
+	}
+
+	StrToUni(title_w, sizeof(title_w), title);
+	StrToUni(path_w, sizeof(path_w), path);
+
+	return MsInstallServiceW(name, title_w, description, path_w);
+}
+bool MsInstallServiceW(char *name, wchar_t *title, wchar_t *description, wchar_t *path)
+{
+	return MsInstallServiceExW(name, title, description, path, NULL);
+}
+bool MsInstallServiceExW(char *name, wchar_t *title, wchar_t *description, wchar_t *path, UINT *error_code)
+{
+	SC_HANDLE sc, service;
+	bool ret = false;
+	wchar_t name_w[MAX_SIZE];
+	static UINT temp_int = 0;
+	// 引数チェック
+	if (name == NULL || title == NULL || path == NULL)
+	{
+		return false;
+	}
+	if (ms->IsNt == false)
+	{
+		return false;
+	}
+	if (error_code == NULL)
+	{
+		error_code = &temp_int;
+	}
+
+	*error_code = 0;
+
+	StrToUni(name_w, sizeof(name_w), name);
+
+	sc = ms->nt->OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+	if (sc == NULL)
+	{
+		*error_code = GetLastError();
+		return false;
+	}
+
+	service = ms->nt->CreateServiceW(sc, name_w, title, SERVICE_ALL_ACCESS,
+		SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS , SERVICE_AUTO_START,
+		SERVICE_ERROR_NORMAL, path, NULL, NULL, NULL, NULL, NULL);
+
+	if (service != NULL)
+	{
+		ret = true;
+
+		if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
+		{
+			SERVICE_DESCRIPTIONW d;
+			SERVICE_FAILURE_ACTIONS action;
+			SC_ACTION *e;
+			Zero(&d, sizeof(d));
+			d.lpDescription = description;
+			ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &d);
+			Zero(&action, sizeof(action));
+			e = ZeroMalloc(sizeof(SC_ACTION) * 3);
+			e[0].Delay = 10000; e[0].Type = SC_ACTION_RESTART;
+			e[1].Delay = 10000; e[1].Type = SC_ACTION_RESTART;
+			e[2].Delay = 10000; e[2].Type = SC_ACTION_RESTART;
+			action.cActions = 3;
+			action.lpsaActions = e;
+			action.dwResetPeriod = 1 * 60 * 60 * 24;
+			ms->nt->ChangeServiceConfig2(service, SERVICE_CONFIG_FAILURE_ACTIONS, &action);
+
+			Free(e);
+		}
+
+		ms->nt->CloseServiceHandle(service);
+	}
+	else
+	{
+		*error_code = GetLastError();
+	}
+
+	ms->nt->CloseServiceHandle(sc);
+
+	if (ret)
+	{
+		SleepThread(2000);
+	}
+
+	return ret;
+}
+
+// 指定したサービスがインストールされているかどうか調べる
+bool MsIsServiceInstalled(char *name)
+{
+	SC_HANDLE sc;
+	SC_HANDLE service;
+	bool ret = false;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+	if (ms->IsNt == false)
+	{
+		return false;
+	}
+
+	sc = ms->nt->OpenSCManager(NULL, NULL, GENERIC_READ);
+	if (sc == NULL)
+	{
+		return false;
+	}
+
+	service = ms->nt->OpenService(sc, name, GENERIC_READ);
+	if (service != NULL)
+	{
+		ret = true;
+	}
+
+	ms->nt->CloseServiceHandle(service);
+	ms->nt->CloseServiceHandle(sc);
+
+	return ret;
+}
+
+// プロセスの強制終了
+void MsTerminateProcess()
+{
+	TerminateProcess(GetCurrentProcess(), 0);
+	_exit(0);
+}
+
+// プロセス ID の取得
+UINT MsGetProcessId()
+{
+	return GetCurrentProcessId();
+}
+
+// MS 構造体の取得
+MS *MsGetMs()
+{
+	return ms;
+}
+
+// スレッドの優先順位を最低にする
+void MsSetThreadPriorityIdle()
+{
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
+}
+
+// スレッドの優先順位を上げる
+void MsSetThreadPriorityHigh()
+{
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
+}
+
+// スレッドの優先順位を下げる
+void MsSetThreadPriorityLow()
+{
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL);
+}
+
+// スレッドの優先順位を最高にする
+void MsSetThreadPriorityRealtime()
+{
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
+}
+
+// スレッドの優先順位を戻す
+void MsRestoreThreadPriority()
+{
+	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
+}
+
+// TCP 設定アプリケーションを表示するべきかどうかチェックする
+bool MsIsShouldShowTcpConfigApp()
+{
+	MS_TCP tcp1, tcp2;
+	if (MsIsTcpConfigSupported() == false)
+	{
+		return false;
+	}
+
+	MsGetTcpConfig(&tcp1);
+	if (MsLoadTcpConfigReg(&tcp2) == false)
+	{
+		return true;
+	}
+
+	if (Cmp(&tcp1, &tcp2, sizeof(MS_TCP) != 0))
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// レジストリの一時設定内容データを Windows の TCP パラメータに適用する
+void MsApplyTcpConfig()
+{
+	if (MsIsTcpConfigSupported())
+	{
+		MS_TCP tcp;
+
+		if (MsLoadTcpConfigReg(&tcp))
+		{
+			MsSetTcpConfig(&tcp);
+		}
+	}
+}
+
+// 現在の状態で TCP の動的構成がサポートされているかどうかチェックする
+bool MsIsTcpConfigSupported()
+{
+	if (MsIsNt() && MsIsAdmin())
+	{
+		UINT type = GetOsInfo()->OsType;
+
+		if (GET_KETA(type, 100) >= 2)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// TCP 設定をレジストリ設定から読み込む
+bool MsLoadTcpConfigReg(MS_TCP *tcp)
+{
+	// 引数チェック
+	if (tcp == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt())
+	{
+		Zero(tcp, sizeof(MS_TCP));
+
+		if (MsRegIsValueEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "RecvWindowSize", true) == false ||
+			MsRegIsValueEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "SendWindowSize", true) == false)
+		{
+			return false;
+		}
+
+		tcp->RecvWindowSize = MsRegReadIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "RecvWindowSize", true);
+		tcp->SendWindowSize = MsRegReadIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "SendWindowSize", true);
+
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+// TCP 設定をレジストリから削除する
+void MsDeleteTcpConfigReg()
+{
+	if (MsIsNt() && MsIsAdmin())
+	{
+		MsRegDeleteKeyEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, true);
+	}
+}
+
+// TCP 設定をレジストリ設定に書き込む
+void MsSaveTcpConfigReg(MS_TCP *tcp)
+{
+	// 引数チェック
+	if (tcp == NULL)
+	{
+		return;
+	}
+
+	if (MsIsNt() && MsIsAdmin())
+	{
+		MsRegWriteIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "RecvWindowSize", tcp->RecvWindowSize, true);
+		MsRegWriteIntEx(REG_LOCAL_MACHINE, MS_REG_TCP_SETTING_KEY, "SendWindowSize", tcp->SendWindowSize, true);
+	}
+}
+
+// 現在の TCP 設定を取得する
+void MsGetTcpConfig(MS_TCP *tcp)
+{
+	// 引数チェック
+	if (tcp == NULL)
+	{
+		return;
+	}
+
+	Zero(tcp, sizeof(MS_TCP));
+
+	if (MsIsNt())
+	{
+		// ネットワーク設定初期化
+		MsInitGlobalNetworkConfig();
+
+		// GlobalMaxTcpWindowSize または TcpWindowSize の値が存在すれば読み込む
+		tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "TcpWindowSize"));
+		tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "GlobalMaxTcpWindowSize"));
+		tcp->RecvWindowSize = MAX(tcp->RecvWindowSize, MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "DefaultReceiveWindow"));
+
+		// DefaultSendWindow の値が存在すれば読み込む
+		tcp->SendWindowSize = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "DefaultSendWindow");
+	}
+}
+
+// TCP 設定を書き込む
+void MsSetTcpConfig(MS_TCP *tcp)
+{
+	// 引数チェック
+	if (tcp == NULL)
+	{
+		return;
+	}
+
+	if (MsIsNt() && MsIsAdmin())
+	{
+		bool window_scaling = false;
+		UINT tcp1323opts;
+
+		if (tcp->RecvWindowSize >= 65536 || tcp->SendWindowSize >= 65536)
+		{
+			window_scaling = true;
+		}
+
+		// Tcp1323Opts の設定
+		tcp1323opts = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "Tcp1323Opts");
+		if (window_scaling)
+		{
+			if (tcp1323opts == 0)
+			{
+				tcp1323opts = 1;
+			}
+			if (tcp1323opts == 2)
+			{
+				tcp1323opts = 3;
+			}
+		}
+		else
+		{
+			if (tcp1323opts == 1)
+			{
+				tcp1323opts = 0;
+			}
+			if (tcp1323opts == 3)
+			{
+				tcp1323opts = 2;
+			}
+		}
+		MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "Tcp1323Opts", tcp1323opts);
+
+		// 受信ウインドウの設定
+		if (tcp->RecvWindowSize == 0)
+		{
+			MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
+				"DefaultReceiveWindow");
+			MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"TcpWindowSize");
+			MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"GlobalMaxTcpWindowSize");
+		}
+		else
+		{
+			MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
+				"DefaultReceiveWindow", tcp->RecvWindowSize);
+			MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"TcpWindowSize", tcp->RecvWindowSize);
+			MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"GlobalMaxTcpWindowSize", tcp->RecvWindowSize);
+		}
+
+		// 送信ウインドウの設定
+		if (tcp->SendWindowSize == 0)
+		{
+			MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
+				"DefaultSendWindow");
+		}
+		else
+		{
+			MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
+				"DefaultSendWindow", tcp->SendWindowSize);
+		}
+	}
+}
+
+// グローバルなネットワーク設定を初期化する
+void MsInitGlobalNetworkConfig()
+{
+	if (MsIsNt())
+	{
+		UINT current_window_size;
+
+		if (MsRegReadInt(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+			"packetix_no_optimize") == 0)
+
+		{
+			// TCP コネクション数を最大にする
+			MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"TcpNumConnections", TCP_MAX_NUM_CONNECTIONS);
+
+			// タスク オフロードを無効化する
+			MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"DisableTaskOffload", 1);
+		}
+
+		current_window_size = MsRegReadInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "TcpWindowSize");
+
+		if (current_window_size == 65535 || current_window_size == 5980160 ||
+			current_window_size == 16777216 || current_window_size == 16777214)
+		{
+			// 古いバージョンの VPN が書き込んでしまった変な値を削除する
+			MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
+				"DefaultReceiveWindow");
+			MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters",
+				"DefaultSendWindow");
+			MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"Tcp1323Opts");
+			MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"TcpWindowSize");
+			MsRegDeleteValue(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"GlobalMaxTcpWindowSize");
+
+			// vpn_no_change = true にする
+			MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", "vpn_no_change", 1);
+			MsRegWriteInt(REG_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\AFD\\Parameters", "vpn_no_change", 1);
+		}
+	}
+	else
+	{
+		if (MsRegReadInt(REG_LOCAL_MACHINE,
+			"System\\CurrentControlSet\\Services\\VxD\\MSTCP",
+			"packetix_no_optimize") == 0)
+		{
+			// DeadGWDetect を無効にする
+			MsRegWriteStr(REG_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\VxD\\MSTCP",
+				"DeadGWDetect", "0");
+		}
+	}
+
+	MsApplyTcpConfig();
+}
+
+// 仮想 LAN カードをアップグレードする
+bool MsUpgradeVLan(char *tag_name, char *connection_tag_name, char *instance_name)
+{
+	wchar_t infpath[MAX_PATH];
+	char hwid[MAX_PATH];
+	wchar_t hwid_w[MAX_PATH];
+	bool ret = false;
+	bool need_reboot;
+	bool before_status;
+	UCHAR old_mac_address[6];
+	char *s;
+	NO_WARNING *nw;
+	char sen_sys[MAX_PATH];
+	// 引数チェック
+	if (instance_name == NULL || tag_name == NULL || connection_tag_name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		// Windows 9x ではアップグレードできない
+		return false;
+	}
+
+	Zero(hwid, sizeof(hwid));
+	Format(hwid, sizeof(hwid), DRIVER_DEVICE_ID_TAG, instance_name);
+	StrToUni(hwid_w, sizeof(hwid_w), hwid);
+
+	// 指定された名前の仮想 LAN カードがすでに登録されているかどうかを調べる
+	if (MsIsVLanExists(tag_name, instance_name) == false)
+	{
+		// 登録されていない
+		return false;
+	}
+
+	// 現在使用している .sys ファイル名を取得する
+	if (MsGetSenDeiverFilename(sen_sys, sizeof(sen_sys), instance_name) == false)
+	{
+		// 不明なので新しいファイル名を作成する
+		if (MsMakeNewSenDriverFilename(sen_sys, sizeof(sen_sys)) == false)
+		{
+			// 失敗
+			return false;
+		}
+	}
+
+	// 現在の動作状況を取得する
+	before_status = MsIsVLanEnabled(instance_name);
+
+	// 以前の MAC アドレスを取得する
+	s = MsGetMacAddress(tag_name, instance_name);
+	if (s == NULL)
+	{
+		Zero(old_mac_address, 6);
+	}
+	else
+	{
+		BUF *b;
+		b = StrToBin(s);
+		Free(s);
+
+		if (b->Size == 6)
+		{
+			Copy(old_mac_address, b->Buf, b->Size);
+		}
+		else
+		{
+			Zero(old_mac_address, 6);
+		}
+
+		FreeBuf(b);
+	}
+
+	// インストール開始
+	if (MsStartDriverInstall(instance_name, IsZero(old_mac_address, 6) ? NULL : old_mac_address, sen_sys) == false)
+	{
+		return false;
+	}
+	MsGetDriverPath(instance_name, NULL, NULL, infpath, NULL, sen_sys);
+
+	nw = NULL;
+
+	//if (MsIsVista() == false)
+	{
+		nw = MsInitNoWarning();
+	}
+
+	// インストールを行う
+	if (ms->nt->UpdateDriverForPlugAndPlayDevicesW(
+		NULL, hwid_w, infpath, 1, &need_reboot))
+	{
+		ret = true;
+	}
+	MsFreeNoWarning(nw);
+
+	// インストール完了
+	MsFinishDriverInstall(instance_name, sen_sys);
+
+	MsInitNetworkConfig(tag_name, instance_name, connection_tag_name);
+
+	// 動作を復元する
+	if (before_status)
+	{
+		MsEnableVLan(instance_name);
+	}
+	else
+	{
+		MsDisableVLan(instance_name);
+	}
+
+	return ret;
+}
+
+// Windows 9x 用テスト
+void MsWin9xTest()
+{
+}
+
+// 仮想 LAN カードの CompatibleIDs を更新する
+void MsUpdateCompatibleIDs(char *instance_name)
+{
+	TOKEN_LIST *t;
+	char id[MAX_SIZE];
+	char device_title[MAX_SIZE];
+	char device_title_old[MAX_SIZE];
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return;
+	}
+
+	Format(id, sizeof(id), DRIVER_DEVICE_ID_TAG, instance_name);
+	Format(device_title, sizeof(device_title), VLAN_ADAPTER_NAME_TAG, instance_name);
+	Format(device_title_old, sizeof(device_title_old), "---dummy-string-ut--", instance_name);
+
+	t = MsRegEnumKey(REG_LOCAL_MACHINE, "Enum\\Root\\Net");
+	if (t != NULL)
+	{
+		UINT i;
+		for (i = 0;i < t->NumTokens;i++)
+		{
+			char keyname[MAX_PATH];
+			char *str;
+			char *title;
+
+			Format(keyname, sizeof(keyname), "Enum\\Root\\Net\\%s", t->Token[i]);
+
+			title = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "DeviceDesc");
+
+			if (title != NULL)
+			{
+				if (StrCmpi(title, device_title) == 0 || StrCmpi(title, device_title_old) == 0)
+				{
+					Format(keyname, sizeof(keyname), "Enum\\Root\\Net\\%s",t->Token[i]);
+					str = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "CompatibleIDs");
+					if (str != NULL)
+					{
+						Free(str);
+					}
+					else
+					{
+						MsRegWriteStr(REG_LOCAL_MACHINE, keyname, "CompatibleIDs", id);
+					}
+				}
+				Free(title);
+			}
+		}
+
+		FreeToken(t);
+	}
+
+	MsRegWriteStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup", "SourcePath",
+		ms->System32Dir);
+}
+
+// 仮想 LAN カードをインストールする (Win9x 用)
+bool MsInstallVLan9x(char *instance_name)
+{
+	char sysdir[MAX_PATH];
+	char infdir[MAX_PATH];
+	char otherdir[MAX_PATH];
+	char syspath[MAX_PATH];
+	char syspath2[MAX_PATH];
+	char infpath[MAX_PATH];
+	char vpn16[MAX_PATH];
+	char infpath_src[MAX_PATH];
+	char syspath_src[MAX_PATH];
+	char sen_sys[MAX_PATH];
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return false;
+	}
+
+	StrCpy(sysdir, sizeof(sysdir), MsGetSystem32Dir());
+	Format(infdir, sizeof(infdir), "%s\\inf", MsGetWindowsDir());
+	Format(otherdir, sizeof(otherdir), "%s\\other", infdir);
+	Format(syspath, sizeof(syspath), "%s\\Sen_%s.sys", sysdir, instance_name);
+	Format(syspath2, sizeof(syspath2), "%s\\Sen_%s.sys", infdir, instance_name);
+	Format(infpath, sizeof(infpath), "%s\\Sen_%s.inf", infdir, instance_name);
+	Format(vpn16, sizeof(vpn16), "%s\\vpn16.exe", MsGetMyTempDir());
+
+	MakeDir(otherdir);
+
+	Format(sen_sys, sizeof(sen_sys), DRIVER_INSTALL_SYS_NAME_TAG, instance_name);
+
+	// vpn16.exe のコピー
+	FileCopy("|vpn16.exe", vpn16);
+
+	// インストール開始
+	if (MsStartDriverInstall(instance_name, NULL, sen_sys) == false)
+	{
+		return false;
+	}
+	MsGetDriverPathA(instance_name, NULL, NULL, infpath_src, syspath_src, sen_sys);
+
+	// inf ファイルのコピー
+	FileCopy(infpath_src, infpath);
+
+	// sys ファイルのコピー
+	FileCopy(syspath_src, syspath);
+
+	// デバイスドライバのインストール
+	if (Run(vpn16, instance_name, false, true) == false)
+	{
+		return false;
+	}
+
+	// CompatibleIDs の更新
+	MsUpdateCompatibleIDs(instance_name);
+
+	return true;
+}
+
+// 子ウインドウ列挙プロシージャ
+bool CALLBACK MsEnumChildWindowProc(HWND hWnd, LPARAM lParam)
+{
+	LIST *o = (LIST *)lParam;
+
+	if (o != NULL)
+	{
+		MsEnumChildWindows(o, hWnd);
+	}
+
+	return true;
+}
+
+// 指定したウインドウとその子ウインドウをすべて列挙する
+LIST *MsEnumChildWindows(LIST *o, HWND hWnd)
+{
+	// 引数チェック
+	if (hWnd == NULL)
+	{
+		return NULL;
+	}
+
+	if (o == NULL)
+	{
+		o = NewListFast(NULL);
+	}
+
+	MsAddWindowToList(o, hWnd);
+
+	EnumChildWindows(hWnd, MsEnumChildWindowProc, (LPARAM)o);
+
+	return o;
+}
+
+// ウインドウをリストに追加する
+void MsAddWindowToList(LIST *o, HWND hWnd)
+{
+	// 引数チェック
+	if (o == NULL || hWnd == NULL)
+	{
+		return;
+	}
+
+	if (IsInList(o, hWnd) == false)
+	{
+		Add(o, hWnd);
+	}
+}
+
+// スレッドの所有するウインドウの列挙
+bool CALLBACK MsEnumThreadWindowProc(HWND hWnd, LPARAM lParam)
+{
+	LIST *o = (LIST *)lParam;
+
+	if (o == NULL)
+	{
+		return false;
+	}
+
+	MsEnumChildWindows(o, hWnd);
+
+	return true;
+}
+
+// ウインドウ列挙プロシージャ
+BOOL CALLBACK EnumTopWindowProc(HWND hWnd, LPARAM lParam)
+{
+	LIST *o = (LIST *)lParam;
+	HWND hParent;
+	char c1[MAX_SIZE], c2[MAX_SIZE];
+	// 引数チェック
+	if (hWnd == NULL || o == NULL)
+	{
+		return TRUE;
+	}
+
+	Zero(c1, sizeof(c1));
+	Zero(c2, sizeof(c2));
+
+	hParent = GetParent(hWnd);
+
+	GetClassName(hWnd, c1, sizeof(c1));
+
+	if (hParent != NULL)
+	{
+		GetClassName(hParent, c2, sizeof(c2));
+	}
+
+	if (StrCmpi(c1, "SysIPAddress32") != 0 && (IsEmptyStr(c2) || StrCmpi(c2, "SysIPAddress32") != 0))
+	{
+		AddWindow(o, hWnd);
+	}
+
+	return TRUE;
+}
+
+// 子ウインドウ列挙プロシージャ
+BOOL CALLBACK EnumChildWindowProc(HWND hWnd, LPARAM lParam)
+{
+	ENUM_CHILD_WINDOW_PARAM *p = (ENUM_CHILD_WINDOW_PARAM *)lParam;
+	LIST *o;
+	HWND hParent;
+	char c1[MAX_SIZE], c2[MAX_SIZE];
+	// 引数チェック
+	if (hWnd == NULL || p == NULL)
+	{
+		return TRUE;
+	}
+
+	o = p->o;
+
+	Zero(c1, sizeof(c1));
+	Zero(c2, sizeof(c2));
+
+	hParent = GetParent(hWnd);
+
+	GetClassName(hWnd, c1, sizeof(c1));
+
+	if (hParent != NULL)
+	{
+		GetClassName(hParent, c2, sizeof(c2));
+	}
+
+	if (p->include_ipcontrol || (StrCmpi(c1, "SysIPAddress32") != 0 && (IsEmptyStr(c2) || StrCmpi(c2, "SysIPAddress32") != 0)))
+	{
+		AddWindow(o, hWnd);
+
+		if (p->no_recursion == false)
+		{
+			EnumChildWindows(hWnd, EnumChildWindowProc, (LPARAM)p);
+		}
+	}
+
+	return TRUE;
+}
+LIST *EnumAllWindow()
+{
+	return EnumAllWindowEx(false, false);
+}
+LIST *EnumAllWindowEx(bool no_recursion, bool include_ipcontrol)
+{
+	ENUM_CHILD_WINDOW_PARAM p;
+	LIST *o = NewWindowList();
+
+	Zero(&p, sizeof(p));
+	p.o = o;
+	p.no_recursion = no_recursion;
+	p.include_ipcontrol = include_ipcontrol;
+
+	EnumWindows(EnumChildWindowProc, (LPARAM)&p);
+
+	return o;
+}
+LIST *EnumAllTopWindow()
+{
+	LIST *o = NewWindowList();
+
+	EnumWindows(EnumTopWindowProc, (LPARAM)o);
+
+	return o;
+}
+
+// 特定のウインドウの中にあるすべての子ウインドウを列挙する
+LIST *EnumAllChildWindow(HWND hWnd)
+{
+	return EnumAllChildWindowEx(hWnd, false, false, false);
+}
+LIST *EnumAllChildWindowEx(HWND hWnd, bool no_recursion, bool include_ipcontrol, bool no_self)
+{
+	ENUM_CHILD_WINDOW_PARAM p;
+	LIST *o = NewWindowList();
+
+	Zero(&p, sizeof(p));
+	p.include_ipcontrol = include_ipcontrol;
+	p.no_recursion = no_recursion;
+	p.o = o;
+
+	if (no_self == false)
+	{
+		AddWindow(o, hWnd);
+	}
+
+	EnumChildWindows(hWnd, EnumChildWindowProc, (LPARAM)&p);
+
+	return o;
+}
+
+// ウインドウリストの解放
+void FreeWindowList(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		HWND *e = LIST_DATA(o, i);
+
+		Free(e);
+	}
+
+	ReleaseList(o);
+}
+
+// ウインドウリストにウインドウを追加
+void AddWindow(LIST *o, HWND hWnd)
+{
+	HWND t, *e;
+	// 引数チェック
+	if (o == NULL || hWnd == NULL)
+	{
+		return;
+	}
+
+	t = hWnd;
+
+	if (Search(o, &t) != NULL)
+	{
+		return;
+	}
+
+	e = ZeroMalloc(sizeof(HWND));
+	*e = hWnd;
+
+	Insert(o, e);
+}
+
+// ウインドウリストの比較
+int CmpWindowList(void *p1, void *p2)
+{
+	HWND *h1, *h2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	h1 = *(HWND **)p1;
+	h2 = *(HWND **)p2;
+	if (h1 == NULL || h2 == NULL)
+	{
+		return 0;
+	}
+
+	return Cmp(h1, h2, sizeof(HWND));
+}
+
+// 新しいウインドウリストの作成
+LIST *NewWindowList()
+{
+	return NewListFast(CmpWindowList);
+}
+
+// Windows Vista かどうか判別
+bool MsIsVista()
+{
+	OS_INFO *info = GetOsInfo();
+
+	if (info == NULL)
+	{
+		return false;
+	}
+
+	if (OS_IS_WINDOWS_NT(info->OsType))
+	{
+		if (GET_KETA(info->OsType, 100) >= 5)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// ウインドウの所有者のプロセスパスを取得する
+bool MsGetWindowOwnerProcessExeName(char *path, UINT size, HWND hWnd)
+{
+	DWORD procId = 0;
+	// 引数チェック
+	if (path == NULL || hWnd == NULL)
+	{
+		return false;
+	}
+
+	GetWindowThreadProcessId(hWnd, &procId);
+	if (procId == 0)
+	{
+		return false;
+	}
+
+	if (MsGetProcessExeName(path, size, procId) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+bool MsGetWindowOwnerProcessExeNameW(wchar_t *path, UINT size, HWND hWnd)
+{
+	DWORD procId = 0;
+	// 引数チェック
+	if (path == NULL || hWnd == NULL)
+	{
+		return false;
+	}
+
+	GetWindowThreadProcessId(hWnd, &procId);
+	if (procId == 0)
+	{
+		return false;
+	}
+
+	if (MsGetProcessExeNameW(path, size, procId) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// プロセス ID からプロセスパスを取得する
+bool MsGetProcessExeName(char *path, UINT size, UINT id)
+{
+	LIST *o;
+	MS_PROCESS *proc;
+	bool ret = false;
+	// 引数チェック
+	if (path == NULL)
+	{
+		return false;
+	}
+
+	o = MsGetProcessList();
+	proc = MsSearchProcessById(o, id);
+
+	if (proc != NULL)
+	{
+		ret = true;
+		StrCpy(path, size, proc->ExeFilename);
+	}
+
+	MsFreeProcessList(o);
+
+	return ret;
+}
+bool MsGetProcessExeNameW(wchar_t *path, UINT size, UINT id)
+{
+	LIST *o;
+	MS_PROCESS *proc;
+	bool ret = false;
+	// 引数チェック
+	if (path == NULL)
+	{
+		return false;
+	}
+
+	o = MsGetProcessList();
+	proc = MsSearchProcessById(o, id);
+
+	if (proc != NULL)
+	{
+		ret = true;
+		UniStrCpy(path, size, proc->ExeFilenameW);
+	}
+
+	MsFreeProcessList(o);
+
+	return ret;
+}
+
+// 警告ダイアログを閉じる
+bool MsCloseWarningWindow(UINT thread_id)
+{
+	UINT i;
+	LIST *o;
+	bool ret = false;
+
+	if (MsIsVista() == false)
+	{
+		o = NewListFast(NULL);
+		EnumThreadWindows(thread_id, MsEnumThreadWindowProc, (LPARAM)o);
+	}
+	else
+	{
+		o = EnumAllTopWindow();
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		HWND hWnd;
+		
+		if (MsIsVista() == false)
+		{
+			hWnd = LIST_DATA(o, i);
+		}
+		else
+		{
+			hWnd = *((HWND *)LIST_DATA(o, i));
+		}
+
+		if (hWnd != NULL)
+		{
+			OS_INFO *info = GetOsInfo();
+
+			if (MsIsNt())
+			{
+				// このウインドウがドライバの警告画面かどうかを取得する
+				if (MsIsVista() == false)
+				{
+					// Windows Vista 以外
+					HWND hStatic, hOk, hCancel, hDetail;
+
+					hStatic = GetDlgItem(hWnd, 0x14C1);
+					hOk = GetDlgItem(hWnd, 0x14B7);
+					hCancel = GetDlgItem(hWnd, 0x14BA);
+					hDetail = GetDlgItem(hWnd, 0x14B9);
+
+					if ((hStatic != NULL || hDetail != NULL) && hOk != NULL && hCancel != NULL)
+					{
+						char tmp[MAX_SIZE];
+						bool b = false;
+
+						if (GetClassName(hStatic, tmp, sizeof(tmp)) != 0)
+						{
+							if (StrCmpi(tmp, "static") == 0)
+							{
+								b = true;
+							}
+						}
+
+						if (GetClassName(hDetail, tmp, sizeof(tmp)) != 0)
+						{
+							if (StrCmpi(tmp, "button") == 0)
+							{
+								b = true;
+							}
+						}
+
+						if (b)
+						{
+							if (GetClassName(hOk, tmp, sizeof(tmp)) != 0)
+							{
+								if (StrCmpi(tmp, "button") == 0)
+								{
+									if (GetClassName(hCancel, tmp, sizeof(tmp)) != 0)
+									{
+										if (StrCmpi(tmp, "button") == 0)
+										{
+											// 発見したので OK ボタンを押す
+											PostMessage(hWnd, WM_COMMAND, 0x14B7, 0);
+
+											ret = true;
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+				else
+				{
+					// Windows Vista
+					char exe[MAX_PATH];
+
+					if (MsGetWindowOwnerProcessExeName(exe, sizeof(exe), hWnd))
+					{
+						if (EndWith(exe, "rundll32.exe"))
+						{
+							LIST *o;
+							HWND h;
+							UINT i;
+
+							o = EnumAllChildWindow(hWnd);
+
+							if (o != NULL)
+							{
+								for (i = 0;i < LIST_NUM(o);i++)
+								{
+									char tmp[MAX_SIZE];
+
+									h = *((HWND *)LIST_DATA(o, i));
+
+									Zero(tmp, sizeof(tmp));
+									GetClassNameA(h, tmp, sizeof(tmp));
+
+									if (StrCmpi(tmp, "DirectUIHWND") == 0)
+									{
+										LIST *o = EnumAllChildWindow(h);
+
+										if (o != NULL)
+										{
+											UINT j;
+											UINT numDirectUIHWND = 0;
+											UINT numButton = 0;
+											HWND hButton1 = NULL;
+											HWND hButton2 = NULL;
+
+											for (j = 0;j < LIST_NUM(o);j++)
+											{
+												HWND hh;
+												char tmp[MAX_SIZE];
+
+												hh = *((HWND *)LIST_DATA(o, j));
+
+												Zero(tmp, sizeof(tmp));
+												GetClassNameA(hh, tmp, sizeof(tmp));
+
+												if (StrCmpi(tmp, "DirectUIHWND") == 0)
+												{
+													numDirectUIHWND++;
+												}
+
+												if (StrCmpi(tmp, "button") == 0)
+												{
+													numButton++;
+													if (hButton1 == NULL)
+													{
+														hButton1 = hh;
+													}
+													else
+													{
+														hButton2 = hh;
+													}
+												}
+											}
+
+											if (numDirectUIHWND == 1 && numButton == 2)
+											{
+												if (hButton1 != NULL && hButton2 != NULL)
+												{
+													HWND hButton;
+													HWND hParent;
+													RECT r1, r2;
+
+													GetWindowRect(hButton1, &r1);
+													GetWindowRect(hButton2, &r2);
+
+													hButton = hButton1;
+
+													if (r1.top < r2.top)
+													{
+														hButton = hButton2;
+													}
+
+													hParent = GetParent(hButton);
+
+													// 発見したので OK ボタンを押す
+													PostMessage(hParent, WM_COMMAND, 1, 0);
+
+													ret = true;
+												}
+											}
+
+											FreeWindowList(o);
+										}
+									}
+								}
+
+								FreeWindowList(o);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if (MsIsVista() == false)
+	{
+		ReleaseList(o);
+	}
+	else
+	{
+		FreeWindowList(o);
+	}
+
+	return ret;
+}
+
+// 警告を出さないようにするためのスレッド
+void MsNoWarningThreadProc(THREAD *thread, void *param)
+{
+	NO_WARNING *nw;
+	UINT interval;
+	UINT i;
+	bool found0 = false;
+	// 引数チェック
+	if (thread == NULL)
+	{
+		return;
+	}
+
+	nw = (NO_WARNING *)param;
+
+	nw->NoWarningThread = thread;
+	AddRef(thread->ref);
+
+	NoticeThreadInit(thread);
+
+	interval = 50;
+
+	if (MsIsVista())
+	{
+		interval = 1000;
+	}
+
+	i = 0;
+
+	while (nw->Halt == false)
+	{
+		bool found;
+
+		// 警告ダイアログを閉じる
+		found = MsCloseWarningWindow(nw->ThreadId);
+		if (i == 0)
+		{
+			found0 = found;
+		}
+		else
+		{
+			if (found0 == false && found)
+			{
+				break;
+			}
+		}
+		i++;
+
+		// 親スレッドが指示するまでループする
+		Wait(nw->HaltEvent, interval);
+	}
+}
+
+// 警告音を消す処理の初期化
+char *MsNoWarningSoundInit()
+{
+	char *ret = MsRegReadStr(REG_CURRENT_USER, "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", "");
+
+	if (IsEmptyStr(ret))
+	{
+		Free(ret);
+		ret = NULL;
+	}
+	else
+	{
+		MsRegWriteStr(REG_CURRENT_USER,
+			"AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",
+			"", "");
+	}
+
+	return ret;
+}
+
+// 警告音を消す処理の解放
+void MsNoWarningSoundFree(char *s)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	MsRegWriteStrExpand(REG_CURRENT_USER,
+		"AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",
+		"", s);
+
+	Free(s);
+}
+
+// 警告を出さないようにする処理の開始
+NO_WARNING *MsInitNoWarning()
+{
+	wchar_t *tmp;
+	THREAD *thread;
+	NO_WARNING *nw = ZeroMalloc(sizeof(NO_WARNING));
+
+	// 現在のサウンドファイル名を取得する
+	tmp = MsRegReadStrW(REG_CURRENT_USER, "AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current", "");
+	if (UniIsEmptyStr(tmp) == false)
+	{
+		nw->SoundFileName = CopyUniStr(tmp);
+
+		MsRegWriteStrW(REG_CURRENT_USER,
+			"AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",
+			"", L"");
+	}
+
+	Free(tmp);
+
+	nw->ThreadId = GetCurrentThreadId();
+	nw->HaltEvent = NewEvent();
+
+	thread = NewThread(MsNoWarningThreadProc, nw);
+	WaitThreadInit(thread);
+
+	ReleaseThread(thread);
+
+	return nw;
+}
+
+// 警告を出さないようにする処理の終了
+void MsFreeNoWarning(NO_WARNING *nw)
+{
+	// 引数チェック
+	if (nw == NULL)
+	{
+		return;
+	}
+
+	nw->Halt = true;
+	Set(nw->HaltEvent);
+
+	WaitThread(nw->NoWarningThread, INFINITE);
+	ReleaseThread(nw->NoWarningThread);
+
+	ReleaseEvent(nw->HaltEvent);
+
+	if (nw->SoundFileName != NULL)
+	{
+		MsRegWriteStrExpandW(REG_CURRENT_USER,
+			"AppEvents\\Schemes\\Apps\\.Default\\SystemAsterisk\\.Current",
+			"", nw->SoundFileName);
+
+		Free(nw->SoundFileName);
+	}
+
+	Free(nw);
+}
+
+// 仮想 LAN カードをインストールする
+bool MsInstallVLan(char *tag_name, char *connection_tag_name, char *instance_name)
+{
+	wchar_t infpath[MAX_PATH];
+	wchar_t inf_class_name[MAX_PATH];
+	GUID inf_class_guid;
+	HDEVINFO device_info;
+	SP_DEVINFO_DATA device_info_data;
+	char hwid[MAX_PATH];
+	wchar_t hwid_w[MAX_PATH];
+	bool ret = false;
+	bool need_reboot;
+	char sen_sys[MAX_PATH];
+	UINT i;
+	// 引数チェック
+	if (instance_name == NULL || tag_name == NULL || connection_tag_name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		// Windows 9x 用
+		return MsInstallVLan9x(instance_name);
+	}
+
+	Zero(hwid, sizeof(hwid));
+	Format(hwid, sizeof(hwid), DRIVER_DEVICE_ID_TAG, instance_name);
+	StrToUni(hwid_w, sizeof(hwid_w), hwid);
+
+	// 指定された名前の仮想 LAN カードがすでに登録されているかどうかを調べる
+	if (MsIsVLanExists(tag_name, instance_name))
+	{
+		// すでに登録されている
+		return false;
+	}
+
+	// インストール先 .sys ファイル名の決定
+	if (MsMakeNewSenDriverFilename(sen_sys, sizeof(sen_sys)) == false)
+	{
+		return false;
+	}
+
+	// インストール開始
+	if (MsStartDriverInstall(instance_name, NULL, sen_sys) == false)
+	{
+		return false;
+	}
+	MsGetDriverPath(instance_name, NULL, NULL, infpath, NULL, sen_sys);
+
+	// inf ファイルのクラス GUID を取得する
+	if (SetupDiGetINFClassW(infpath, &inf_class_guid, inf_class_name, sizeof(inf_class_name), NULL))
+	{
+		// デバイス情報セットを取得する
+		device_info = SetupDiCreateDeviceInfoList(&inf_class_guid, NULL);
+		if (device_info != INVALID_HANDLE_VALUE)
+		{
+			// Windows 2000 以降
+			Zero(&device_info_data, sizeof(device_info_data));
+			device_info_data.cbSize = sizeof(device_info_data);
+			if (SetupDiCreateDeviceInfoW(device_info, inf_class_name, &inf_class_guid,
+				NULL, NULL, DICD_GENERATE_ID, &device_info_data))
+			{
+				// レジストリ情報を設定する
+				if (SetupDiSetDeviceRegistryProperty(device_info, &device_info_data,
+					SPDRP_HARDWAREID, (BYTE *)hwid, sizeof(hwid)))
+				{
+					NO_WARNING *nw = NULL;
+					
+					//if (MsIsVista() == false)
+					{
+						nw = MsInitNoWarning();
+					}
+
+					// クラスインストーラを起動する
+					if (SetupDiCallClassInstaller(DIF_REGISTERDEVICE, device_info,
+						&device_info_data))
+					{
+						// インストールを行う
+						if (ms->nt->UpdateDriverForPlugAndPlayDevicesW(
+							NULL, hwid_w, infpath, 1, &need_reboot))
+						{
+							ret = true;
+						}
+						else
+						{
+							// インストール失敗
+							SetupDiCallClassInstaller(DIF_REMOVE, device_info,
+								&device_info_data);
+						}
+					}
+					else
+					{
+						Debug("SetupDiCallClassInstaller Error: %X\n", GetLastError());
+					}
+
+					MsFreeNoWarning(nw);
+				}
+			}
+			// デバイス情報セットを削除する
+			SetupDiDestroyDeviceInfoList(device_info);
+		}
+	}
+
+	// インストール完了
+	MsFinishDriverInstall(instance_name, sen_sys);
+
+	for (i = 0;i < 5;i++)
+	{
+		MsInitNetworkConfig(tag_name, instance_name, connection_tag_name);
+		SleepThread(MsIsVista() ? 1000 : 300);
+	}
+
+	if (ret)
+	{
+		MsDisableVLan(instance_name);
+		MsEnableVLan(instance_name);
+	}
+
+	return ret;
+}
+
+// デバイス ID からデバイス情報を取得する
+HDEVINFO MsGetDevInfoFromDeviceId(SP_DEVINFO_DATA *dev_info_data, char *device_id)
+{
+	HDEVINFO dev_info;
+	SP_DEVINFO_LIST_DETAIL_DATA detail_data;
+	SP_DEVINFO_DATA data;
+	UINT i;
+	bool found;
+	char target_name[MAX_SIZE];
+	// 引数チェック
+	if (dev_info_data == NULL || device_id == NULL)
+	{
+		return NULL;
+	}
+
+	StrCpy(target_name, sizeof(target_name), device_id);
+
+	// デバイス情報リストを作成
+	dev_info = SetupDiGetClassDevsEx(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT, NULL, NULL, NULL);
+	if (dev_info == NULL)
+	{
+		return NULL;
+	}
+
+	Zero(&detail_data, sizeof(detail_data));
+	detail_data.cbSize = sizeof(detail_data);
+	if (SetupDiGetDeviceInfoListDetail(dev_info, &detail_data) == false)
+	{
+		MsDestroyDevInfo(dev_info);
+		return NULL;
+	}
+
+	Zero(&data, sizeof(data));
+	data.cbSize = sizeof(data);
+
+	// 列挙開始
+	found = false;
+	for (i = 0;SetupDiEnumDeviceInfo(dev_info, i, &data);i++)
+	{
+		char *buffer;
+		UINT buffer_size = 8092;
+		DWORD data_type;
+
+		buffer = ZeroMalloc(buffer_size);
+
+		if (SetupDiGetDeviceRegistryProperty(dev_info, &data, SPDRP_HARDWAREID, &data_type, (PBYTE)buffer, buffer_size, NULL))
+		{
+			if (StrCmpi(buffer, target_name) == 0)
+			{
+				// 発見
+				found = true;
+			}
+		}
+
+		Free(buffer);
+
+		if (found)
+		{
+			break;
+		}
+	}
+
+	if (found == false)
+	{
+		MsDestroyDevInfo(dev_info);
+		return NULL;
+	}
+	else
+	{
+		Copy(dev_info_data, &data, sizeof(data));
+		return dev_info;
+	}
+}
+
+// 指定したデバイスが動作中かどうかを調べる
+bool MsIsDeviceRunning(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)
+{
+	SP_DEVINFO_LIST_DETAIL_DATA detail;
+	UINT status = 0, problem = 0;
+	// 引数チェック
+	if (info == NULL || dev_info_data == NULL)
+	{
+		return false;
+	}
+
+	Zero(&detail, sizeof(detail));
+	detail.cbSize = sizeof(detail);
+
+	if (SetupDiGetDeviceInfoListDetail(info, &detail) == false ||
+		ms->nt->CM_Get_DevNode_Status_Ex(&status, &problem, dev_info_data->DevInst,
+		0, detail.RemoteMachineHandle) != CR_SUCCESS)
+	{
+		return false;
+	}
+
+	if (status & 8)
+	{
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+// 指定したデバイスを開始させる
+bool MsStartDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)
+{
+	SP_PROPCHANGE_PARAMS p;
+	// 引数チェック
+	if (info == NULL || dev_info_data == NULL)
+	{
+		return false;
+	}
+
+	Zero(&p, sizeof(p));
+	p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
+	p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
+	p.StateChange = DICS_ENABLE;
+	p.Scope = DICS_FLAG_GLOBAL;
+	if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)))
+	{
+		SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data);
+	}
+
+	Zero(&p, sizeof(p));
+	p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
+	p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
+	p.StateChange = DICS_ENABLE;
+	p.Scope = DICS_FLAG_CONFIGSPECIFIC;
+
+	if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == false ||
+		SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// 指定したデバイスを停止させる
+bool MsStopDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)
+{
+	SP_PROPCHANGE_PARAMS p;
+	// 引数チェック
+	if (info == NULL || dev_info_data == NULL)
+	{
+		return false;
+	}
+
+	Zero(&p, sizeof(p));
+	p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
+	p.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
+	p.StateChange = DICS_DISABLE;
+	p.Scope = DICS_FLAG_CONFIGSPECIFIC;
+
+	if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == false ||
+		SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, info, dev_info_data) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// 指定したデバイスを削除する
+bool MsDeleteDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data)
+{
+	SP_REMOVEDEVICE_PARAMS p;
+	SP_DEVINFO_LIST_DETAIL_DATA detail;
+	char device_id[MAX_PATH];
+	// 引数チェック
+	if (info == NULL || dev_info_data == NULL)
+	{
+		return false;
+	}
+
+	Zero(&detail, sizeof(detail));
+	detail.cbSize = sizeof(detail);
+
+	if (SetupDiGetDeviceInfoListDetail(info, &detail) == false ||
+		ms->nt->CM_Get_Device_ID_Ex(dev_info_data->DevInst, device_id, sizeof(device_id),
+		0, detail.RemoteMachineHandle) != CR_SUCCESS)
+	{
+		return false;
+	}
+
+	Zero(&p, sizeof(p));
+	p.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
+	p.ClassInstallHeader.InstallFunction = DIF_REMOVE;
+	p.Scope = DI_REMOVEDEVICE_GLOBAL;
+
+	if (SetupDiSetClassInstallParams(info, dev_info_data, &p.ClassInstallHeader, sizeof(p)) == false)
+	{
+		Debug("SetupDiSetClassInstallParams Failed. Err=%u\n", GetLastError());
+		return false;
+	}
+
+	if (SetupDiCallClassInstaller(DIF_REMOVE, info, dev_info_data) == false)
+	{
+		Debug("SetupDiCallClassInstaller Failed. Err=%u\n", GetLastError());
+		return false;
+	}
+
+	return true;
+}
+
+// 仮想 LAN カードを有効にする
+bool MsEnableVLan(char *instance_name)
+{
+	char tmp[MAX_PATH];
+	HDEVINFO h;
+	bool ret;
+	SP_DEVINFO_DATA data;
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		return false;
+	}
+
+	Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);
+
+	h = MsGetDevInfoFromDeviceId(&data, tmp);
+	if (h == NULL)
+	{
+		return false;
+	}
+
+	ret = MsStartDevice(h, &data);
+
+	MsDestroyDevInfo(h);
+
+	return ret;
+}
+
+// 仮想 LAN カードを無効にする
+bool MsDisableVLan(char *instance_name)
+{
+	char tmp[MAX_PATH];
+	HDEVINFO h;
+	bool ret;
+	SP_DEVINFO_DATA data;
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		return false;
+	}
+
+	Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);
+
+	h = MsGetDevInfoFromDeviceId(&data, tmp);
+	if (h == NULL)
+	{
+		return false;
+	}
+
+	ret = MsStopDevice(h, &data);
+
+	MsDestroyDevInfo(h);
+
+	return ret;
+}
+
+// 仮想 LAN カードを再起動する
+void MsRestartVLan(char *instance_name)
+{
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return;
+	}
+
+	if (MsIsNt() == false)
+	{
+		return;
+	}
+
+	if (MsIsVLanEnabled(instance_name) == false)
+	{
+		return;
+	}
+
+	MsDisableVLan(instance_name);
+	MsEnableVLan(instance_name);
+}
+
+// 仮想 LAN カードが動作しているかどうか取得する
+bool MsIsVLanEnabled(char *instance_name)
+{
+	char tmp[MAX_PATH];
+	HDEVINFO h;
+	bool ret;
+	SP_DEVINFO_DATA data;
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		return true;
+	}
+
+	Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);
+
+	h = MsGetDevInfoFromDeviceId(&data, tmp);
+	if (h == NULL)
+	{
+		return false;
+	}
+
+	ret = MsIsDeviceRunning(h, &data);
+
+	MsDestroyDevInfo(h);
+
+	return ret;
+}
+
+// 仮想 LAN カードをアンインストールする
+bool MsUninstallVLan(char *instance_name)
+{
+	char tmp[MAX_PATH];
+	HDEVINFO h;
+	bool ret;
+	SP_DEVINFO_DATA data;
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return false;
+	}
+
+	Format(tmp, sizeof(tmp), DRIVER_DEVICE_ID_TAG, instance_name);
+
+	h = MsGetDevInfoFromDeviceId(&data, tmp);
+	if (h == NULL)
+	{
+		return false;
+	}
+
+	ret = MsDeleteDevice(h, &data);
+
+	MsDestroyDevInfo(h);
+
+	return ret;
+}
+
+// 汎用テスト関数
+void MsTest()
+{
+}
+
+// デバイス情報の破棄
+void MsDestroyDevInfo(HDEVINFO info)
+{
+	// 引数チェック
+	if (info == NULL)
+	{
+		return;
+	}
+
+	SetupDiDestroyDeviceInfoList(info);
+}
+
+// ドライバインストールの開始
+bool MsStartDriverInstall(char *instance_name, UCHAR *mac_address, char *sen_sys)
+{
+	wchar_t src_inf[MAX_PATH];
+	wchar_t src_sys[MAX_PATH];
+	wchar_t dest_inf[MAX_PATH];
+	wchar_t dest_sys[MAX_PATH];
+	UCHAR mac_address_bin[6];
+	char mac_address_str[32];
+	UINT size;
+	char *tmp;
+	BUF *b;
+	IO *io;
+	// 引数チェック
+	if (instance_name == NULL || sen_sys == NULL)
+	{
+		return false;
+	}
+
+	MsGetDriverPath(instance_name, src_inf, src_sys, dest_inf, dest_sys, sen_sys);
+
+	// INF ファイルの処理
+	io = FileOpenW(src_inf, false);
+	if (io == NULL)
+	{
+		return false;
+	}
+
+	size = FileSize(io);
+	tmp = ZeroMalloc(size * 2);
+	if (FileRead(io, tmp, size) == false)
+	{
+		FileClose(io);
+		Free(tmp);
+		return false;
+	}
+
+	FileClose(io);
+
+	if (mac_address == NULL)
+	{
+		MsGenMacAddress(mac_address_bin);
+	}
+	else
+	{
+		Copy(mac_address_bin, mac_address, 6);
+	}
+
+	BinToStr(mac_address_str, sizeof(mac_address_str), mac_address_bin, sizeof(mac_address_bin));
+
+	//ReplaceStrEx(tmp, size * 2, tmp, "$TAG_DRIVER_VER$", DRIVER_VER_STR, false);
+	ReplaceStrEx(tmp, size * 2, tmp, "$TAG_INSTANCE_NAME$", instance_name, false);
+	ReplaceStrEx(tmp, size * 2, tmp, "$TAG_MAC_ADDRESS$", mac_address_str, false);
+	ReplaceStrEx(tmp, size * 2, tmp, "$TAG_SYS_NAME$", sen_sys, false);
+
+	if (MsIsVista())
+	{
+		//ReplaceStrEx(tmp, size * 2, tmp, "\"100\"", "\"2000\"", false);
+	}
+
+	io = FileCreateW(dest_inf);
+	if (io == NULL)
+	{
+		Free(tmp);
+		return false;
+	}
+
+	FileWrite(io, tmp, StrLen(tmp));
+	FileClose(io);
+
+	Free(tmp);
+
+	// SYS ファイルの処理
+	b = ReadDumpW(src_sys);
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	if (DumpBufW(b, dest_sys) == false)
+	{
+		FreeBuf(b);
+		return false;
+	}
+
+	FreeBuf(b);
+
+	return true;
+}
+
+// MAC アドレスの生成
+void MsGenMacAddress(UCHAR *mac)
+{
+	UCHAR hash_src[40];
+	UCHAR hash[20];
+	UINT64 now;
+	// 引数チェック
+	if (mac == NULL)
+	{
+		return;
+	}
+
+	Rand(hash_src, 40);
+	now = SystemTime64();
+	Copy(hash_src, &now, sizeof(now));
+
+	Hash(hash, hash_src, sizeof(hash_src), true);
+
+	mac[0] = 0x00;
+	mac[1] = 0xAC;
+	mac[2] = hash[0];
+	mac[3] = hash[1];
+	mac[4] = hash[2];
+	mac[5] = hash[3];
+}
+
+// ドライバインストールの完了
+void MsFinishDriverInstall(char *instance_name, char *sen_sys)
+{
+	wchar_t src_inf[MAX_PATH];
+	wchar_t src_sys[MAX_PATH];
+	wchar_t dest_inf[MAX_PATH];
+	wchar_t dest_sys[MAX_PATH];
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return;
+	}
+
+	MsGetDriverPath(instance_name, src_inf, src_sys, dest_inf, dest_sys, sen_sys);
+
+	// ファイル削除
+	FileDeleteW(dest_inf);
+	FileDeleteW(dest_sys);
+}
+
+// ドライバファイルのパスの取得
+void MsGetDriverPath(char *instance_name, wchar_t *src_inf, wchar_t *src_sys, wchar_t *dest_inf, wchar_t *dest_sys, char *sen_sys)
+{
+	wchar_t *src_filename;
+	wchar_t *src_sys_filename;
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return;
+	}
+
+	src_filename = DRIVER_INF_FILE_NAME;
+	src_sys_filename = DRIVER_SYS_FILE_NAME;
+
+	if (MsIsNt() == false)
+	{
+		src_filename = DRIVER_INF_FILE_NAME_9X;
+		src_sys_filename = DRIVER_SYS_FILE_NAME_9X;
+	}
+	else if (MsIsIA64() || MsIsX64())
+	{
+		if (MsIsX64())
+		{
+			src_filename = DRIVER_INF_FILE_NAME_X64;
+			src_sys_filename = DRIVER_SYS_FILE_NAME_X64;
+		}
+		else
+		{
+			src_filename = DRIVER_INF_FILE_NAME_IA64;
+			src_sys_filename = DRIVER_SYS_FILE_NAME_IA64;
+		}
+	}
+
+	if (src_inf != NULL)
+	{
+		UniStrCpy(src_inf, MAX_PATH, src_filename);
+	}
+
+	if (src_sys != NULL)
+	{
+		UniStrCpy(src_sys, MAX_PATH, src_sys_filename);
+	}
+
+	if (dest_inf != NULL)
+	{
+		char inf_name[MAX_PATH];
+		Format(inf_name, sizeof(inf_name), DRIVER_INSTALL_INF_NAME_TAG, instance_name);
+		UniFormat(dest_inf, MAX_PATH, L"%s\\%S", ms->MyTempDirW, inf_name);
+	}
+
+	if (dest_sys != NULL)
+	{
+		char sys_name[MAX_PATH];
+		StrCpy(sys_name, sizeof(sys_name), sen_sys);
+		UniFormat(dest_sys, MAX_PATH, L"%s\\%S", ms->MyTempDirW, sys_name);
+	}
+}
+void MsGetDriverPathA(char *instance_name, char *src_inf, char *src_sys, char *dest_inf, char *dest_sys, char *sen_sys)
+{
+	wchar_t src_inf_w[MAX_PATH];
+	wchar_t src_sys_w[MAX_PATH];
+	wchar_t dest_inf_w[MAX_PATH];
+	wchar_t dest_sys_w[MAX_PATH];
+
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		return;
+	}
+
+	MsGetDriverPath(instance_name, src_inf_w, src_sys_w, dest_inf_w, dest_sys_w, sen_sys);
+
+	UniToStr(src_inf, MAX_PATH, src_inf_w);
+	UniToStr(src_sys, MAX_PATH, src_sys_w);
+	UniToStr(dest_inf, MAX_PATH, dest_inf_w);
+	UniToStr(dest_sys, MAX_PATH, dest_sys_w);
+}
+
+// 指定された名前の仮想 LAN カードがすでに登録されているかどうかを調べる
+bool MsIsVLanExists(char *tag_name, char *instance_name)
+{
+	char *guid;
+	// 引数チェック
+	if (instance_name == NULL || tag_name == NULL)
+	{
+		return false;
+	}
+
+	guid = MsGetNetworkAdapterGuid(tag_name, instance_name);
+	if (guid == NULL)
+	{
+		return false;
+	}
+
+	Free(guid);
+	return true;
+}
+
+// ネットワーク設定ダイアログを表示する
+// ※ これはもう使っていない。うまく動かないからである。
+//    代わりに ShowWindowsNetworkConnectionDialog() を使うこと。
+bool MsShowNetworkConfiguration(HWND hWnd)
+{
+	IO *link_file = MsCreateTempFileByExt(".lnk");
+	char name[MAX_PATH];
+	SHELLEXECUTEINFO info;
+
+	// ファイル名確保
+	StrCpy(name, sizeof(name), link_file->Name);
+
+	// ショートカット作成
+	if (FileWrite(link_file, network_connection_link, sizeof(network_connection_link)) == false)
+	{
+		FileCloseAndDelete(link_file);
+		return false;
+	}
+
+	FileClose(link_file);
+
+	// ショートカットの実行
+	Zero(&info, sizeof(info));
+	info.cbSize = sizeof(info);
+	info.hwnd = (HWND)hWnd;
+	info.lpVerb = "open";
+	info.lpFile = name;
+	info.nShow = SW_SHOWDEFAULT;
+	info.fMask = SEE_MASK_NOCLOSEPROCESS;
+	if (ShellExecuteEx(&info) == false)
+	{
+		FileDelete(name);
+		return false;
+	}
+
+	// プロセス終了まで待機
+	WaitForSingleObject(info.hProcess, INFINITE);
+	CloseHandle(info.hProcess);
+
+	// ファイルの削除
+	FileDelete(name);
+
+	return true;
+}
+
+// 拡張子を元に一時ファイルを作成する
+IO *MsCreateTempFileByExt(char *ext)
+{
+	char *tmp = MsCreateTempFileNameByExt(ext);
+	IO *ret;
+
+	if (tmp == NULL)
+	{
+		return NULL;
+	}
+
+	ret = FileCreate(tmp);
+	Free(tmp);
+
+	return ret;
+}
+
+// 拡張子を指定するとその拡張子を持つ一時ファイルを作成する
+char *MsCreateTempFileNameByExt(char *ext)
+{
+	UCHAR rand[2];
+	char *ret = NULL;
+	// 引数チェック
+	if (ext == NULL)
+	{
+		ext = "tmp";
+	}
+	if (ext[0] == '.')
+	{
+		ext++;
+	}
+	if (StrLen(ext) == 0)
+	{
+		ext = "tmp";
+	}
+
+	while (true)
+	{
+		char new_filename[MAX_PATH];
+		char *fullpath;
+		char rand_str[MAX_PATH];
+		IO *io;
+		Rand(rand, sizeof(rand));
+
+		BinToStr(rand_str, sizeof(rand_str), rand, sizeof(rand));
+		Format(new_filename, sizeof(new_filename), "__%s.%s", rand_str, ext);
+
+		fullpath = MsCreateTempFileName(new_filename);
+		io = FileOpen(fullpath, false);
+		if (io == NULL)
+		{
+			ret = fullpath;
+			break;
+		}
+		FileClose(io);
+
+		Free(fullpath);
+	}
+
+	return ret;
+}
+
+// 一時ファイルを作成する
+IO *MsCreateTempFile(char *name)
+{
+	IO *ret;
+	char *tmp;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	tmp = MsCreateTempFileName(name);
+	if (tmp == NULL)
+	{
+		return NULL;
+	}
+
+	ret = FileCreate(tmp);
+	Free(tmp);
+
+	return ret;
+}
+
+// 一時ファイル名を作成する
+char *MsCreateTempFileName(char *name)
+{
+	char tmp[MAX_PATH];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	Format(tmp, sizeof(tmp), "%s\\%s", ms->MyTempDir, name);
+
+	return CopyStr(tmp);
+}
+
+// システムに残っているが使用されていない VPN 用一時ディレクトリを削除する
+void MsDeleteTempDir()
+{
+	HANDLE h;
+	wchar_t dir_mask[MAX_PATH];
+	WIN32_FIND_DATAA data_a;
+	WIN32_FIND_DATAW data_w;
+
+	Zero(&data_a, sizeof(data_a));
+	Zero(&data_w, sizeof(data_w));
+
+	UniFormat(dir_mask, sizeof(dir_mask), L"%s\\*", ms->TempDirW);
+
+	if (IsNt())
+	{
+		h = FindFirstFileW(dir_mask, &data_w);
+	}
+	else
+	{
+		char *tmp_a = CopyUniToStr(dir_mask);
+
+		h = FindFirstFileA(tmp_a, &data_a);
+
+		Free(tmp_a);
+	}
+
+	if (h != INVALID_HANDLE_VALUE)
+	{
+		bool b = true;
+
+		do
+		{
+			if (IsNt() == false)
+			{
+				Zero(&data_w, sizeof(data_w));
+				StrToUni(data_w.cFileName, sizeof(data_w.cFileName), data_a.cFileName);
+				data_w.dwFileAttributes = data_a.dwFileAttributes;
+				data_w.ftCreationTime = data_a.ftCreationTime;
+				data_w.ftLastWriteTime = data_a.ftLastWriteTime;
+				data_w.nFileSizeHigh = data_a.nFileSizeHigh;
+				data_w.nFileSizeLow = data_a.nFileSizeLow;
+			}
+
+			if (UniStrCmpi(data_w.cFileName, L".") != 0 &&
+				UniStrCmpi(data_w.cFileName, L"..") != 0)
+			{
+				if (data_w.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+				{
+					if (UniStartWith(data_w.cFileName, L"VPN_") && UniStrLen(data_w.cFileName) == 8)
+					{
+						wchar_t lock_file_name[MAX_PATH];
+						wchar_t dir_name[MAX_PATH];
+						bool delete_now = false;
+						IO *io;
+
+						UniFormat(dir_name, sizeof(dir_name), L"%s\\%s",
+							ms->TempDirW, data_w.cFileName);
+						MsGenLockFile(lock_file_name, sizeof(lock_file_name), dir_name);
+
+						io = FileOpenExW(lock_file_name, false, false);
+						if (io != NULL)
+						{
+							// ロックファイルがロックされていなければ削除マーク
+							FileClose(io);
+							io = FileOpenW(lock_file_name, true);
+							if (io != NULL)
+							{
+								delete_now = true;
+								FileClose(io);
+							}
+						}
+						else
+						{
+							DIRLIST *d;
+
+							// 中にあるすべてのファイルがロックされていなければ削除マーク
+							delete_now = true;
+
+							d = EnumDirW(dir_name);
+							if (d != NULL)
+							{
+								UINT i;
+
+								for (i = 0;i < d->NumFiles;i++)
+								{
+									wchar_t full_path[MAX_PATH];
+
+									UniFormat(full_path, sizeof(full_path), L"%s\\%s", dir_name, d->File[i]->FileNameW);
+
+									io = FileOpenW(full_path, true);
+									if (io != NULL)
+									{
+										delete_now = true;
+										FileClose(io);
+									}
+								}
+								FreeDir(d);
+							}
+						}
+						if (delete_now)
+						{
+							MsDeleteAllFileW(dir_name);
+
+							Win32DeleteDirW(dir_name);
+						}
+					}
+				}
+			}
+
+
+			Zero(&data_w, sizeof(data_w));
+			Zero(&data_a, sizeof(data_a));
+
+			if (IsNt())
+			{
+				b = FindNextFileW(h, &data_w);
+			}
+			else
+			{
+				b = FindNextFileA(h, &data_a);
+			}
+		}
+		while (b);
+
+		FindClose(h);
+	}
+}
+
+// 指定したディレクトリ内のファイルをすべて削除する
+void MsDeleteAllFile(char *dir)
+{
+	HANDLE h;
+	char file_mask[MAX_PATH];
+	WIN32_FIND_DATA data;
+	// 引数チェック
+	if (dir == NULL || IsEmptyStr(dir))
+	{
+		return;
+	}
+
+	Format(file_mask, sizeof(file_mask), "%s\\*.*", dir);
+
+	h = FindFirstFile(file_mask, &data);
+	if (h != INVALID_HANDLE_VALUE)
+	{
+		do
+		{
+			if (StrCmpi(data.cFileName, ".") != 0 &&
+				StrCmpi(data.cFileName, "..") != 0)
+			{
+				char fullpath[MAX_PATH];
+				Format(fullpath, sizeof(fullpath), "%s\\%s", dir, data.cFileName);
+				if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == false)
+				{
+					DeleteFile(fullpath);
+				}
+				else
+				{
+					MsDeleteAllFile(fullpath);
+					RemoveDirectory(fullpath);
+				}
+			}
+		}
+		while (FindNextFile(h, &data));
+
+		FindClose(h);
+	}
+}
+void MsDeleteAllFileW(wchar_t *dir)
+{
+	HANDLE h;
+	wchar_t file_mask[MAX_PATH];
+	WIN32_FIND_DATAW data;
+	// 引数チェック
+	if (dir == NULL || UniIsEmptyStr(dir))
+	{
+		return;
+	}
+
+	if (IsNt() == false)
+	{
+		char *dir_a = CopyUniToStr(dir);
+
+		MsDeleteAllFile(dir_a);
+
+		Free(dir_a);
+
+		return;
+	}
+
+	UniFormat(file_mask, sizeof(file_mask), L"%s\\*.*", dir);
+
+	h = FindFirstFileW(file_mask, &data);
+	if (h != INVALID_HANDLE_VALUE)
+	{
+		do
+		{
+			if (UniStrCmpi(data.cFileName, L".") != 0 &&
+				UniStrCmpi(data.cFileName, L"..") != 0)
+			{
+				wchar_t fullpath[MAX_PATH];
+
+				UniFormat(fullpath, sizeof(fullpath), L"%s\\%s", dir, data.cFileName);
+
+				if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == false)
+				{
+					DeleteFileW(fullpath);
+				}
+				else
+				{
+					MsDeleteAllFileW(fullpath);
+					RemoveDirectoryW(fullpath);
+				}
+			}
+		}
+		while (FindNextFileW(h, &data));
+
+		FindClose(h);
+	}
+}
+
+// 一時ディレクトリを初期化する
+void MsInitTempDir()
+{
+	wchar_t tmp[MAX_PATH];
+	wchar_t tmp2[16];
+	UCHAR random[2];
+	wchar_t lockfilename[MAX_PATH];
+	UINT num = 0;
+
+	// 使われていない一時ディレクトリの削除
+	MsDeleteTempDir();
+
+	// 一時ディレクトリ名の決定
+	while (true)
+	{
+		random[0] = rand() % 256;
+		random[1] = rand() % 256;
+		BinToStrW(tmp2, sizeof(tmp2), random, sizeof(random));
+
+		UniFormat(tmp, sizeof(tmp), L"%s\\VPN_%s", ms->TempDirW, tmp2);
+
+		// ディレクトリの作成
+		if (MakeDirW(tmp))
+		{
+			break;
+		}
+
+		if ((num++) >= 100)
+		{
+			// 何度も失敗する
+			char msg[MAX_SIZE];
+			Format(msg, sizeof(msg),
+				"Couldn't create Temporary Directory: %s\r\n\r\n"
+				"Please contact your system administrator.",
+				tmp);
+			exit(0);
+		}
+	}
+
+	ms->MyTempDirW = CopyUniStr(tmp);
+	ms->MyTempDir = CopyUniToStr(tmp);
+
+	// ロックファイルの作成
+	MsGenLockFile(lockfilename, sizeof(lockfilename), ms->MyTempDirW);
+	ms->LockFile = FileCreateW(lockfilename);
+}
+
+// 一時ディレクトリを解放する
+void MsFreeTempDir()
+{
+	wchar_t lock_file_name[MAX_SIZE];
+
+	// ロックファイルの削除
+	MsGenLockFile(lock_file_name, sizeof(lock_file_name), ms->MyTempDirW);
+	FileClose(ms->LockFile);
+
+	// メモリ解放
+	Free(ms->MyTempDir);
+	Free(ms->MyTempDirW);
+	ms->MyTempDir = NULL;
+	ms->MyTempDirW = NULL;
+
+	// ディレクトリ削除
+	MsDeleteTempDir();
+}
+
+// ロックファイル名の生成
+void MsGenLockFile(wchar_t *name, UINT size, wchar_t *temp_dir)
+{
+	// 引数チェック
+	if (name == NULL || temp_dir == NULL)
+	{
+		return;
+	}
+
+	UniFormat(name, size, L"%s\\VPN_Lock.dat", temp_dir);
+}
+
+// ネットワーク設定の初期化
+void MsInitNetworkConfig(char *tag_name, char *instance_name, char *connection_tag_name)
+{
+	char tmp[MAX_SIZE];
+	char *config_str;
+	// 引数チェック
+	if (tag_name == NULL || instance_name == NULL || connection_tag_name == NULL)
+	{
+		return;
+	}
+
+	if (MsIsNt() == false)
+	{
+		return;
+	}
+
+	// 文字列などの設定
+	Format(tmp, sizeof(tmp), connection_tag_name, instance_name);
+	MsSetNetworkConfig(tag_name, instance_name, tmp, true);
+
+	// インターフェイス・メトリック値の設定
+	config_str = MsGetNetworkAdapterGuid(tag_name, instance_name);
+	if (config_str != NULL)
+	{
+		Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%s",
+			config_str);
+
+		MsRegWriteInt(REG_LOCAL_MACHINE, tmp, "InterfaceMetric", 1);
+		MsRegWriteInt(REG_LOCAL_MACHINE, tmp, "EnableDeadGWDetect", 0);
+
+		if (MsRegReadInt(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+			"packetix_no_optimize") == 0)
+		{
+			MsRegWriteInt(REG_LOCAL_MACHINE,
+				"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
+				"EnableDeadGWDetect",
+				0);
+		}
+
+		Free(config_str);
+	}
+}
+
+// ネットワーク設定を行う
+void MsSetNetworkConfig(char *tag_name, char *instance_name, char *friendly_name, bool show_icon)
+{
+	char *key;
+	char *old_name;
+	// 引数チェック
+	if (tag_name == NULL || instance_name == NULL || friendly_name == NULL)
+	{
+		return;
+	}
+
+	key = MsGetNetworkConfigRegKeyNameFromInstanceName(tag_name, instance_name);
+	if (key == NULL)
+	{
+		return;
+	}
+
+	old_name = MsRegReadStr(REG_LOCAL_MACHINE, key, "Name");
+	if (old_name != NULL)
+	{
+		if (MsIsVista())
+		{
+			char arg[MAX_PATH];
+			char netsh[MAX_PATH];
+
+			Format(netsh, sizeof(netsh), "%s\\netsh.exe", MsGetSystem32Dir());
+
+			if (StrCmp(old_name, friendly_name) != 0)
+			{
+				Format(arg, sizeof(arg), "interface set interface name=\"%s\" newname=\"%s\"",
+					old_name, friendly_name);
+
+				Run(netsh, arg, true, true);
+			}
+
+			Format(arg, sizeof(arg), "netsh interface ipv4 set interface interface=\"%s\" metric=1",
+				friendly_name);
+
+			Run(netsh, arg, true, true);
+		}
+	}
+
+	if (StrCmp(old_name, friendly_name) != 0)
+	{
+		MsRegWriteStr(REG_LOCAL_MACHINE, key, "Name", friendly_name);
+	}
+
+	MsRegWriteInt(REG_LOCAL_MACHINE, key, "ShowIcon", show_icon ? 1 : 0);
+
+	Free(key);
+
+	Free(old_name);
+}
+
+// ネットワーク設定キー名をインスタンス名から取得
+char *MsGetNetworkConfigRegKeyNameFromInstanceName(char *tag_name, char *instance_name)
+{
+	char *guid, *ret;
+	// 引数チェック
+	if (tag_name == NULL || instance_name == NULL)
+	{
+		return NULL;
+	}
+
+	guid = MsGetNetworkAdapterGuid(tag_name, instance_name);
+	if (guid == NULL)
+	{
+		return NULL;
+	}
+
+	ret = MsGetNetworkConfigRegKeyNameFromGuid(guid);
+
+	Free(guid);
+
+	return ret;
+}
+
+// ネットワーク設定キー名を GUID から取得
+char *MsGetNetworkConfigRegKeyNameFromGuid(char *guid)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (guid == NULL)
+	{
+		return NULL;
+	}
+
+	Format(tmp, sizeof(tmp),
+		"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection",
+		guid);
+
+	return CopyStr(tmp);
+}
+
+// MAC アドレスの設定
+void MsSetMacAddress(char *tag_name, char *instance_name, char *mac_address)
+{
+	TOKEN_LIST *key_list;
+	UINT i;
+	char dest_name[MAX_SIZE];
+	char mac_str[MAX_SIZE];
+	// 引数チェック
+	if (tag_name == NULL || instance_name == NULL)
+	{
+		return;
+	}
+
+	// MAC アドレスの正規化
+	if (NormalizeMacAddress(mac_str, sizeof(mac_str), mac_address) == false)
+	{
+		return;
+	}
+
+	// 目的の名前を生成
+	Format(dest_name, sizeof(dest_name), tag_name, instance_name);
+
+	// キーを列挙
+	if (MsIsNt())
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
+	}
+	else
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"System\\CurrentControlSet\\Services\\Class\\Net");
+	}
+	if (key_list == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < key_list->NumTokens;i++)
+	{
+		char *key_name = key_list->Token[i];
+		char full_key_name[MAX_SIZE];
+		char *driver_desc;
+
+		if (MsIsNt())
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
+				key_name);
+		}
+		else
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"System\\CurrentControlSet\\Services\\Class\\Net\\%s",
+				key_name);
+		}
+
+		// DriverDesc を読み込む
+		driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
+		if (driver_desc != NULL)
+		{
+			if (StrCmpi(dest_name, driver_desc) == 0)
+			{
+				// MAC アドレスの書き込み
+				MsRegWriteStr(REG_LOCAL_MACHINE, full_key_name, "NetworkAddress", mac_str);
+				Free(driver_desc);
+
+				// ドライバの再起動
+				MsRestartVLan(instance_name);
+				break;
+			}
+			Free(driver_desc);
+		}
+	}
+
+	FreeToken(key_list);
+
+	return;
+}
+
+// デバイスドライバのファイル名の取得
+char *MsGetDriverFileName(char *tag_name, char *instance_name)
+{
+	TOKEN_LIST *key_list;
+	UINT i;
+	char *ret = NULL;
+	char dest_name[MAX_SIZE];
+	// 引数チェック
+	if (tag_name == NULL || instance_name == NULL)
+	{
+		return NULL;
+	}
+
+	// 目的の名前を生成
+	Format(dest_name, sizeof(dest_name), tag_name, instance_name);
+
+	// キーを列挙
+	if (MsIsNt())
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
+	}
+	else
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"System\\CurrentControlSet\\Services\\Class\\Net");
+	}
+	if (key_list == NULL)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < key_list->NumTokens;i++)
+	{
+		char *key_name = key_list->Token[i];
+		char full_key_name[MAX_SIZE];
+		char *driver_desc;
+
+		if (MsIsNt())
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
+				key_name);
+		}
+		else
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"System\\CurrentControlSet\\Services\\Class\\Net\\%s",
+				key_name);
+		}
+
+		// DriverDesc を読み込む
+		driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
+		if (driver_desc != NULL)
+		{
+			if (StrCmpi(dest_name, driver_desc) == 0)
+			{
+				// ファイル名を読み込む
+				ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DeviceVxDs");
+				Free(driver_desc);
+				break;
+			}
+			Free(driver_desc);
+		}
+	}
+
+	FreeToken(key_list);
+
+	return ret;
+}
+
+// デバイスドライバのバージョンの取得
+char *MsGetDriverVersion(char *tag_name, char *instance_name)
+{
+	TOKEN_LIST *key_list;
+	TOKEN_LIST *t;
+	UINT i;
+	char *ret = NULL;
+	char dest_name[MAX_SIZE];
+	// 引数チェック
+	if (tag_name == NULL || instance_name == NULL)
+	{
+		return NULL;
+	}
+
+	// 目的の名前を生成
+	Format(dest_name, sizeof(dest_name), tag_name, instance_name);
+
+	// キーを列挙
+	if (MsIsNt())
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
+	}
+	else
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"System\\CurrentControlSet\\Services\\Class\\Net");
+	}
+	if (key_list == NULL)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < key_list->NumTokens;i++)
+	{
+		char *key_name = key_list->Token[i];
+		char full_key_name[MAX_SIZE];
+		char *driver_desc;
+
+		if (MsIsNt())
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
+				key_name);
+		}
+		else
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"System\\CurrentControlSet\\Services\\Class\\Net\\%s",
+				key_name);
+		}
+
+		// DriverDesc を読み込む
+		driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
+		if (driver_desc != NULL)
+		{
+			if (StrCmpi(dest_name, driver_desc) == 0)
+			{
+				// バージョン情報を読み込む
+				ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverVersion");
+				if (ret == NULL)
+				{
+					ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "SenVersion");
+				}
+				Free(driver_desc);
+				break;
+			}
+			Free(driver_desc);
+		}
+	}
+
+	FreeToken(key_list);
+
+	if (ret == NULL)
+	{
+		return NULL;
+	}
+
+	t = ParseToken(ret, ", ");
+	if (t->NumTokens == 2)
+	{
+		Free(ret);
+		ret = CopyStr(t->Token[1]);
+	}
+	FreeToken(t);
+
+	return ret;
+}
+
+// MAC アドレスの取得
+char *MsGetMacAddress(char *tag_name, char *instance_name)
+{
+	TOKEN_LIST *key_list;
+	UINT i;
+	char *ret = NULL;
+	char dest_name[MAX_SIZE];
+	// 引数チェック
+	if (tag_name == NULL || instance_name == NULL)
+	{
+		return NULL;
+	}
+
+	// 目的の名前を生成
+	Format(dest_name, sizeof(dest_name), tag_name, instance_name);
+
+	// キーを列挙
+	if (MsIsNt())
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
+	}
+	else
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"System\\CurrentControlSet\\Services\\Class\\Net");
+	}
+
+	if (key_list == NULL)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < key_list->NumTokens;i++)
+	{
+		char *key_name = key_list->Token[i];
+		char full_key_name[MAX_SIZE];
+		char *driver_desc;
+
+		if (MsIsNt())
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
+				key_name);
+		}
+		else
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"System\\CurrentControlSet\\Services\\Class\\Net\\%s",
+				key_name);
+		}
+
+		// DriverDesc を読み込む
+		driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
+		if (driver_desc != NULL)
+		{
+			if (StrCmpi(dest_name, driver_desc) == 0)
+			{
+				// MAC アドレスを読み込む
+				ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "NetworkAddress");
+
+				if (IsEmptyStr(ret) == false)
+				{
+					// MAC アドレスにハイフンを入れる
+					BUF *b = StrToBin(ret);
+					if (b != NULL && b->Size == 6)
+					{
+						char tmp[MAX_SIZE];
+						MacToStr(tmp, sizeof(tmp), b->Buf);
+
+						Free(ret);
+						ret = CopyStr(tmp);
+					}
+					FreeBuf(b);
+				}
+
+				Free(driver_desc);
+				break;
+			}
+			Free(driver_desc);
+		}
+	}
+
+	FreeToken(key_list);
+
+	return ret;
+}
+
+// 仮想 LAN カードのデバイス名が本当に存在するかどうかチェックする
+bool MsCheckVLanDeviceIdFromRootEnum(char *name)
+{
+	TOKEN_LIST *t;
+	char *root;
+	char *keyname;
+	UINT i;
+	bool ret;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt())
+	{
+		root = "SYSTEM\\CurrentControlSet\\Enum\\Root\\NET";
+		keyname = "HardwareID";
+	}
+	else
+	{
+		root = "Enum\\Root\\Net";
+		keyname = "CompatibleIDs";
+	}
+
+	t = MsRegEnumKey(REG_LOCAL_MACHINE, root);
+	if (t == NULL)
+	{
+		return false;
+	}
+
+	ret = false;
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		char *subname = t->Token[i];
+		char fullname[MAX_SIZE];
+		char *value;
+
+		Format(fullname, sizeof(fullname), "%s\\%s", root, subname);
+
+		value = MsRegReadStr(REG_LOCAL_MACHINE, fullname, keyname);
+		if (value != NULL)
+		{
+			if (StrCmpi(value, name) == 0)
+			{
+				ret = true;
+			}
+			Free(value);
+		}
+
+		if (ret)
+		{
+			break;
+		}
+	}
+
+	FreeToken(t);
+
+	return ret;
+}
+
+// ネットワークアダプタの GUID の取得
+char *MsGetNetworkAdapterGuid(char *tag_name, char *instance_name)
+{
+	TOKEN_LIST *key_list;
+	UINT i;
+	char *ret = NULL;
+	char dest_name[MAX_SIZE];
+	// 引数チェック
+	if (tag_name == NULL || instance_name == NULL)
+	{
+		return NULL;
+	}
+
+	// 目的の名前を生成
+	Format(dest_name, sizeof(dest_name), tag_name, instance_name);
+
+	// キーを列挙
+	if (MsIsNt())
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
+	}
+	else
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"System\\CurrentControlSet\\Services\\Class\\Net");
+	}
+	if (key_list == NULL)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < key_list->NumTokens;i++)
+	{
+		char *key_name = key_list->Token[i];
+		char full_key_name[MAX_SIZE];
+		char *driver_desc;
+		char *device_id;
+
+		if (MsIsNt())
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
+				key_name);
+		}
+		else
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"System\\CurrentControlSet\\Services\\Class\\Net\\%s",
+				key_name);
+		}
+
+		device_id = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "MatchingDeviceId");
+
+		if (device_id != NULL)
+		{
+			if (MsCheckVLanDeviceIdFromRootEnum(device_id))
+			{
+				// DriverDesc を読み込む
+				driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
+				if (driver_desc != NULL)
+				{
+					if (StrCmpi(dest_name, driver_desc) == 0)
+					{
+						// NetCfgInstanceId を読み込む
+						if (MsIsNt())
+						{
+							ret = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "NetCfgInstanceId");
+						}
+						else
+						{
+							ret = CopyStr("");
+						}
+						Free(driver_desc);
+						Free(device_id);
+						break;
+					}
+					Free(driver_desc);
+				}
+			}
+			Free(device_id);
+		}
+	}
+
+	FreeToken(key_list);
+
+	return ret;
+}
+// ネットワーク接続名の取得
+wchar_t *MsGetNetworkConnectionName(char *guid)
+{
+	wchar_t *ncname = NULL;
+	// 引数チェック
+	if (guid == NULL)
+	{
+		return NULL;
+	}
+
+	// ネットワーク接続名を取得
+	if (IsNt() != false && GetOsInfo()->OsType >= OSTYPE_WINDOWS_2000_PROFESSIONAL)
+	{
+		char tmp[MAX_SIZE];
+		Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection", guid);
+		ncname = MsRegReadStrW(REG_LOCAL_MACHINE, tmp, "Name");
+	}
+
+	return ncname;
+}
+
+// 新しい Sen のドライバファイル名を生成
+bool MsMakeNewSenDriverFilename(char *name, UINT size)
+{
+	TOKEN_LIST *t = MsEnumSenDriverFilenames();
+	UINT i;
+	bool ret = false;
+
+	i = 0;
+	while (true)
+	{
+		char tmp[MAX_PATH];
+		UINT n;
+
+		i++;
+		if (i >= 10000)
+		{
+			break;
+		}
+
+		n = Rand32() % DRIVER_INSTALL_SYS_NAME_TAG_MAXID;
+
+		MsGenerateSenDriverFilenameFromInt(tmp, sizeof(tmp), n);
+
+		if (IsInToken(t, tmp) == false)
+		{
+			StrCpy(name, size, tmp);
+			ret = true;
+			break;
+		}
+	}
+
+	FreeToken(t);
+
+	return ret;
+}
+
+// Sen のドライバファイル名を整数から生成
+void MsGenerateSenDriverFilenameFromInt(char *name, UINT size, UINT n)
+{
+	Format(name, size, DRIVER_INSTALL_SYS_NAME_TAG_NEW, n);
+}
+
+// インストールされている Sen のドライバファイル名の列挙
+TOKEN_LIST *MsEnumSenDriverFilenames()
+{
+	TOKEN_LIST *neos = MsEnumNetworkAdaptersSen();
+	LIST *o = NewListFast(NULL);
+	TOKEN_LIST *ret;
+	UINT i;
+
+	for (i = 0;i < neos->NumTokens;i++)
+	{
+		char filename[MAX_PATH];
+		if (MsGetSenDeiverFilename(filename, sizeof(filename), neos->Token[i]))
+		{
+			Add(o, CopyStr(filename));
+		}
+	}
+
+	FreeToken(neos);
+
+	ret = ListToTokenList(o);
+	FreeStrList(o);
+
+	return ret;
+}
+
+// Sen のドライバファイル名を取得
+bool MsGetSenDeiverFilename(char *name, UINT size, char *instance_name)
+{
+	char tmp[MAX_SIZE];
+	char *ret;
+	// 引数チェック
+	if (name == NULL || instance_name == NULL)
+	{
+		return false;
+	}
+
+	Format(tmp, sizeof(tmp), "SYSTEM\\CurrentControlSet\\Services\\Sen_%s", instance_name);
+
+	ret = MsRegReadStr(REG_LOCAL_MACHINE, tmp, "ImagePath");
+	if (ret == NULL)
+	{
+		return false;
+	}
+
+	GetFileNameFromFilePath(name, size, ret);
+	Free(ret);
+
+	return true;
+}
+
+// ネットワークアダプタの列挙 (Sen のみ)
+TOKEN_LIST *MsEnumNetworkAdaptersSen()
+{
+	TOKEN_LIST *key_list;
+	TOKEN_LIST *ret;
+	LIST *o;
+	UINT i;
+
+	// キーを列挙
+	if (MsIsNt())
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
+	}
+	else
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"System\\CurrentControlSet\\Services\\Class\\Net");
+	}
+	if (key_list == NULL)
+	{
+		return NULL;
+	}
+
+	o = NewListFast(CompareStr);
+
+	for (i = 0;i < key_list->NumTokens;i++)
+	{
+		char *key_name = key_list->Token[i];
+		char full_key_name[MAX_SIZE];
+		char *driver_desc;
+		char *device_id;
+
+		if (MsIsNt())
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
+				key_name);
+		}
+		else
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"System\\CurrentControlSet\\Services\\Class\\Net\\%s",
+				key_name);
+		}
+
+		// DriverDesc を読み込む
+		driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
+		if (driver_desc != NULL)
+		{
+			// 特定の名前で始まっているかどうか確認する
+			device_id = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "MatchingDeviceId");
+
+			if (device_id != NULL)
+			{
+				if (MsCheckVLanDeviceIdFromRootEnum(device_id))
+				{
+					char *tag = "senadapter_";
+					if (StartWith(device_id, tag))
+					{
+						char tmp[MAX_SIZE];
+						StrCpy(tmp, sizeof(tmp), &device_id[StrLen(tag)]);
+
+						Add(o, CopyStr(tmp));
+					}
+				}
+				Free(device_id);
+			}
+
+			Free(driver_desc);
+		}
+	}
+
+	FreeToken(key_list);
+
+	ret = ZeroMalloc(sizeof(TOKEN_LIST));
+	ret->NumTokens = LIST_NUM(o);
+	ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
+	for (i = 0;i < ret->NumTokens;i++)
+	{
+		ret->Token[i] = LIST_DATA(o, i);
+	}
+
+	ReleaseList(o);
+
+	return ret;
+}
+
+// ネットワークアダプタの列挙
+TOKEN_LIST *MsEnumNetworkAdapters(char *start_with_name, char *start_with_name_2)
+{
+	TOKEN_LIST *key_list;
+	TOKEN_LIST *ret;
+	LIST *o;
+	UINT i;
+
+	// キーを列挙
+	if (MsIsNt())
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}");
+	}
+	else
+	{
+		key_list = MsRegEnumKey(REG_LOCAL_MACHINE,
+			"System\\CurrentControlSet\\Services\\Class\\Net");
+	}
+	if (key_list == NULL)
+	{
+		return NULL;
+	}
+
+	o = NewListFast(CompareStr);
+
+	for (i = 0;i < key_list->NumTokens;i++)
+	{
+		char *key_name = key_list->Token[i];
+		char full_key_name[MAX_SIZE];
+		char *driver_desc;
+		char *device_id;
+
+		if (MsIsNt())
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002bE10318}\\%s",
+				key_name);
+		}
+		else
+		{
+			Format(full_key_name, sizeof(full_key_name),
+				"System\\CurrentControlSet\\Services\\Class\\Net\\%s",
+				key_name);
+		}
+
+		// DriverDesc を読み込む
+		driver_desc = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "DriverDesc");
+		if (driver_desc != NULL)
+		{
+			// 特定の名前で始まっているかどうか確認する
+			if ((IsEmptyStr(start_with_name) && IsEmptyStr(start_with_name_2)) ||
+				(StartWith(driver_desc, start_with_name) || StartWith(driver_desc, start_with_name_2)))
+			{
+				device_id = MsRegReadStr(REG_LOCAL_MACHINE, full_key_name, "MatchingDeviceId");
+
+				if (device_id != NULL)
+				{
+					if (MsCheckVLanDeviceIdFromRootEnum(device_id))
+					{
+						char instance_name[MAX_SIZE];
+						// 名前からインスタンス名だけを抽出する
+						if (StartWith(driver_desc, start_with_name))
+						{
+							if (StrLen(driver_desc) > (StrLen(start_with_name) + 3))
+							{
+								StrCpy(instance_name, sizeof(instance_name),
+									driver_desc + StrLen(start_with_name) + 3);
+								Add(o, CopyStr(instance_name));
+							}
+						}
+						else
+						{
+							if (StrLen(driver_desc) > (StrLen(start_with_name_2) + 3))
+							{
+								StrCpy(instance_name, sizeof(instance_name),
+									driver_desc + StrLen(start_with_name_2) + 3);
+								Add(o, CopyStr(instance_name));
+							}
+						}
+					}
+					Free(device_id);
+				}
+			}
+
+			Free(driver_desc);
+		}
+	}
+
+	FreeToken(key_list);
+
+	ret = ZeroMalloc(sizeof(TOKEN_LIST));
+	ret->NumTokens = LIST_NUM(o);
+	ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
+	for (i = 0;i < ret->NumTokens;i++)
+	{
+		ret->Token[i] = LIST_DATA(o, i);
+	}
+
+	ReleaseList(o);
+
+	return ret;
+}
+
+// ドメインへのログオンを試行する
+bool MsCheckLogon(wchar_t *username, char *password)
+{
+	wchar_t password_unicode[MAX_SIZE];
+	HANDLE h;
+	// 引数チェック
+	if (username == NULL || password == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		return false;
+	}
+
+	StrToUni(password_unicode, sizeof(password_unicode), password);
+
+	if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
+	{
+		if (ms->nt->LogonUserW(username, NULL, password_unicode, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)
+		{
+			// ログオン失敗
+			return false;
+		}
+	}
+	else
+	{
+		char username_ansi[MAX_SIZE];
+		UniToStr(username_ansi, sizeof(username_ansi), username);
+
+		if (ms->nt->LogonUserA(username_ansi, NULL, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)
+		{
+			// ログオン失敗
+			return false;
+		}
+	}
+
+	CloseHandle(h);
+
+	return true;
+}
+
+// ドメインへのログオンを試行する
+bool MsIsPasswordEmpty(wchar_t *username)
+{
+	HANDLE h;
+	// 引数チェック
+	if (username == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() == false)
+	{
+		return false;
+	}
+
+	if (GET_KETA(GetOsInfo()->OsType, 100) >= 2)
+	{
+		if (ms->nt->LogonUserW(username, NULL, L"", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)
+		{
+			// ログオン失敗
+			if (GetLastError() == 1327)
+			{
+				// パスワードが空
+				return true;
+			}
+			else
+			{
+				// パスワードが間違っている
+				return false;
+			}
+		}
+	}
+	else
+	{
+		char username_ansi[MAX_SIZE];
+		UniToStr(username_ansi, sizeof(username_ansi), username);
+
+		if (ms->nt->LogonUserA(username_ansi, NULL, "", LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &h) == false)
+		{
+			// ログオン失敗
+			if (GetLastError() == 1327)
+			{
+				// パスワードが空
+				return true;
+			}
+			else
+			{
+				// パスワードが間違っている
+				return false;
+			}
+		}
+	}
+
+	CloseHandle(h);
+
+	// ログオン成功ということはパスワードが空ということになる
+	return false;
+}
+
+// シャットダウンの実行 (NT)
+bool MsShutdownEx(bool reboot, bool force, UINT time_limit, char *message)
+{
+	if (MsIsNt() == false)
+	{
+		return MsShutdown(reboot, force);
+	}
+
+	// 特権の取得
+	if (MsEnablePrivilege(SE_SHUTDOWN_NAME, true) == false)
+	{
+		return false;
+	}
+
+	// シャットダウンの実行
+	if (ms->nt->InitiateSystemShutdown(NULL, message, time_limit, force, reboot) == false)
+	{
+		MsEnablePrivilege(SE_SHUTDOWN_NAME, false);
+		return false;
+	}
+
+	// 特権の解放
+	MsEnablePrivilege(SE_SHUTDOWN_NAME, false);
+
+	return true;
+}
+
+// シャットダウンの実行
+bool MsShutdown(bool reboot, bool force)
+{
+	UINT flag = 0;
+	// 特権の取得
+	if (MsEnablePrivilege(SE_SHUTDOWN_NAME, true) == false)
+	{
+		return false;
+	}
+
+	flag |= (reboot ? EWX_REBOOT : EWX_SHUTDOWN);
+	flag |= (force ? EWX_FORCE : 0);
+
+	// シャットダウンの実行
+	if (ExitWindowsEx(flag, 0) == false)
+	{
+		MsEnablePrivilege(SE_SHUTDOWN_NAME, false);
+		return false;
+	}
+
+	// 特権の解放
+	MsEnablePrivilege(SE_SHUTDOWN_NAME, false);
+
+	return true;
+}
+
+// 特権を有効または無効にする
+bool MsEnablePrivilege(char *name, bool enable)
+{
+	HANDLE hToken;
+	NT_API *nt = ms->nt;
+	LUID luid;
+	TOKEN_PRIVILEGES *tp;
+	bool ret;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+	if (MsIsNt() == false)
+	{
+		return true;
+	}
+
+	// プロセストークンを開く
+	if (nt->OpenProcessToken(ms->hCurrentProcess, TOKEN_ADJUST_PRIVILEGES, &hToken) == false)
+	{
+		return false;
+	}
+
+	// ローカル一意識別子を取得する
+	if (nt->LookupPrivilegeValue(NULL, name, &luid) == FALSE)
+	{
+		CloseHandle(hToken);
+		return false;
+	}
+
+	// 特権を有効 / 無効にするための構造体を作成する
+	tp = ZeroMalloc(sizeof(TOKEN_PRIVILEGES));
+	tp->PrivilegeCount = 1;
+	tp->Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
+	Copy(&tp->Privileges[0].Luid, &luid, sizeof(LUID));
+
+	// 特権を操作する
+	ret = nt->AdjustTokenPrivileges(hToken, false, tp, sizeof(TOKEN_PRIVILEGES), 0, 0);
+
+	Free(tp);
+	CloseHandle(hToken);
+
+	return ret;
+}
+
+// 現在の OS が NT 系かどうか取得
+bool MsIsNt()
+{
+	if (ms == NULL)
+	{
+		OSVERSIONINFO os;
+		Zero(&os, sizeof(os));
+		os.dwOSVersionInfoSize = sizeof(os);
+		GetVersionEx(&os);
+		if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
+		{
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+	return ms->IsNt;
+}
+
+// 現在のユーザーが Admin かどうか取得
+bool MsIsAdmin()
+{
+	return ms->IsAdmin;
+}
+
+// NT 系関数のロード
+NT_API *MsLoadNtApiFunctions()
+{
+	NT_API *nt = ZeroMalloc(sizeof(NT_API));
+	OSVERSIONINFO info;
+
+	Zero(&info, sizeof(info));
+	info.dwOSVersionInfoSize = sizeof(info);
+	GetVersionEx(&info);
+
+	nt->hKernel32 = LoadLibrary("kernel32.dll");
+	if (nt->hKernel32 == NULL)
+	{
+		Free(nt);
+		return NULL;
+	}
+
+	nt->hAdvapi32 = LoadLibrary("advapi32.dll");
+	if (nt->hAdvapi32 == NULL)
+	{
+		Free(nt);
+		return NULL;
+	}
+
+	nt->hShell32 = LoadLibrary("shell32.dll");
+	if (nt->hShell32 == NULL)
+	{
+		FreeLibrary(nt->hAdvapi32);
+		Free(nt);
+		return NULL;
+	}
+
+	nt->hPsApi = LoadLibrary("psapi.dll");
+
+	if (info.dwMajorVersion >= 5)
+	{
+		nt->hNewDev = LoadLibrary("newdev.dll");
+		if (nt->hNewDev == NULL)
+		{
+			FreeLibrary(nt->hShell32);
+			FreeLibrary(nt->hAdvapi32);
+			Free(nt);
+			return NULL;
+		}
+
+		nt->hSetupApi = LoadLibrary("setupapi.dll");
+	}
+
+	nt->hSecur32 = LoadLibrary("secur32.dll");
+
+	nt->hUser32 = LoadLibrary("user32.dll");
+
+	nt->hDbgHelp = LoadLibrary("dbghelp.dll");
+
+	// 関数の読み込み
+	nt->IsWow64Process =
+		(BOOL (__stdcall *)(HANDLE,BOOL *))
+		GetProcAddress(nt->hKernel32, "IsWow64Process");
+
+	nt->GetFileInformationByHandle =
+		(BOOL (__stdcall *)(HANDLE,LPBY_HANDLE_FILE_INFORMATION))
+		GetProcAddress(nt->hKernel32, "GetFileInformationByHandle");
+
+	nt->GetProcessHeap =
+		(HANDLE (__stdcall *)())
+		GetProcAddress(nt->hKernel32, "GetProcessHeap");
+
+	nt->SetProcessShutdownParameters =
+		(BOOL (__stdcall *)(DWORD,DWORD))
+		GetProcAddress(nt->hKernel32, "SetProcessShutdownParameters");
+
+	nt->GetNativeSystemInfo =
+		(void (__stdcall *)(SYSTEM_INFO *))
+		GetProcAddress(nt->hKernel32, "GetNativeSystemInfo");
+
+	nt->AdjustTokenPrivileges =
+		(BOOL (__stdcall *)(HANDLE,BOOL,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD))
+		GetProcAddress(nt->hAdvapi32, "AdjustTokenPrivileges");
+
+	nt->LookupPrivilegeValue =
+		(BOOL (__stdcall *)(char *,char *,PLUID))
+		GetProcAddress(nt->hAdvapi32, "LookupPrivilegeValueA");
+
+	nt->OpenProcessToken =
+		(BOOL (__stdcall *)(HANDLE,DWORD,PHANDLE))
+		GetProcAddress(nt->hAdvapi32, "OpenProcessToken");
+
+	nt->InitiateSystemShutdown =
+		(BOOL (__stdcall *)(LPTSTR,LPTSTR,DWORD,BOOL,BOOL))
+		GetProcAddress(nt->hAdvapi32, "InitiateSystemShutdownA");
+
+	nt->LogonUserW =
+		(BOOL (__stdcall *)(wchar_t *,wchar_t *,wchar_t *,DWORD,DWORD,HANDLE *))
+		GetProcAddress(nt->hAdvapi32, "LogonUserW");
+
+	nt->LogonUserA =
+		(BOOL (__stdcall *)(char *,char *,char *,DWORD,DWORD,HANDLE * ))
+		GetProcAddress(nt->hAdvapi32, "LogonUserA");
+
+	nt->DuplicateTokenEx =
+		(BOOL (__stdcall *)(HANDLE,DWORD,SECURITY_ATTRIBUTES *,SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,HANDLE *))
+		GetProcAddress(nt->hAdvapi32, "DuplicateTokenEx");
+
+	nt->ConvertStringSidToSidA =
+		(BOOL (__stdcall *)(LPCSTR,PSID *))
+		GetProcAddress(nt->hAdvapi32, "ConvertStringSidToSidA");
+
+	nt->GetTokenInformation =
+		(BOOL (__stdcall *)(HANDLE,TOKEN_INFORMATION_CLASS,void *,DWORD,PDWORD))
+		GetProcAddress(nt->hAdvapi32, "GetTokenInformation");
+
+	nt->SetTokenInformation =
+		(BOOL (__stdcall *)(HANDLE,TOKEN_INFORMATION_CLASS,void *,DWORD))
+		GetProcAddress(nt->hAdvapi32, "SetTokenInformation");
+
+	nt->CreateProcessAsUserA =
+		(BOOL (__stdcall *)(HANDLE,LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,void *,LPCSTR,LPSTARTUPINFOA,LPPROCESS_INFORMATION))
+		GetProcAddress(nt->hAdvapi32, "CreateProcessAsUserA");
+
+	nt->CreateProcessAsUserW =
+		(BOOL (__stdcall *)(HANDLE,LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES,LPSECURITY_ATTRIBUTES,BOOL,DWORD,void *,LPCWSTR,LPSTARTUPINFOW,LPPROCESS_INFORMATION))
+		GetProcAddress(nt->hAdvapi32, "CreateProcessAsUserW");
+
+	nt->LookupAccountSidA =
+		(BOOL (__stdcall *)(LPCSTR,PSID,LPSTR,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE))
+		GetProcAddress(nt->hAdvapi32, "LookupAccountSidA");
+
+	nt->LookupAccountNameA =
+		(BOOL (__stdcall *)(LPCSTR,LPCSTR,PSID,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE))
+		GetProcAddress(nt->hAdvapi32, "LookupAccountNameA");
+
+	if (info.dwMajorVersion >= 5)
+	{
+		nt->UpdateDriverForPlugAndPlayDevicesW =
+			(BOOL (__stdcall *)(HWND,wchar_t *,wchar_t *,UINT,BOOL *))
+			GetProcAddress(nt->hNewDev, "UpdateDriverForPlugAndPlayDevicesW");
+
+		nt->CM_Get_Device_ID_ExA =
+			(UINT (__stdcall *)(DWORD,char *,UINT,UINT,HANDLE))
+			GetProcAddress(nt->hSetupApi, "CM_Get_Device_ID_ExA");
+
+		nt->CM_Get_DevNode_Status_Ex =
+			(UINT (__stdcall *)(UINT *,UINT *,DWORD,UINT,HANDLE))
+			GetProcAddress(nt->hSetupApi, "CM_Get_DevNode_Status_Ex");
+	}
+
+	nt->hWtsApi32 = LoadLibrary("wtsapi32.dll");
+	if (nt->hWtsApi32 != NULL)
+	{
+		// ターミナルサービス関係の API
+		nt->WTSQuerySessionInformation =
+			(UINT (__stdcall *)(HANDLE,DWORD,WTS_INFO_CLASS,wchar_t *,DWORD *))
+			GetProcAddress(nt->hWtsApi32, "WTSQuerySessionInformationW");
+		nt->WTSFreeMemory =
+			(void (__stdcall *)(void *))
+			GetProcAddress(nt->hWtsApi32, "WTSFreeMemory");
+		nt->WTSDisconnectSession =
+			(BOOL (__stdcall *)(HANDLE,DWORD,BOOL))
+			GetProcAddress(nt->hWtsApi32, "WTSDisconnectSession");
+		nt->WTSEnumerateSessionsA =
+			(BOOL (__stdcall *)(HANDLE,DWORD,DWORD,PWTS_SESSION_INFOA *,DWORD *))
+			GetProcAddress(nt->hWtsApi32, "WTSEnumerateSessionsA");
+	}
+
+	// サービス系 API
+	nt->OpenSCManager =
+		(SC_HANDLE (__stdcall *)(LPCTSTR,LPCTSTR,DWORD))
+		GetProcAddress(nt->hAdvapi32, "OpenSCManagerA");
+	nt->CreateServiceA =
+		(SC_HANDLE (__stdcall *)(SC_HANDLE,LPCTSTR,LPCTSTR,DWORD,DWORD,DWORD,DWORD,LPCTSTR,LPCTSTR,LPDWORD,LPCTSTR,LPCTSTR,LPCTSTR))
+		GetProcAddress(nt->hAdvapi32, "CreateServiceA");
+	nt->CreateServiceW =
+		(SC_HANDLE (__stdcall *)(SC_HANDLE,LPCWSTR,LPCWSTR,DWORD,DWORD,DWORD,DWORD,LPCWSTR,LPCWSTR,LPDWORD,LPCWSTR,LPCWSTR,LPCWSTR))
+		GetProcAddress(nt->hAdvapi32, "CreateServiceW");
+	nt->ChangeServiceConfig2 =
+		(BOOL (__stdcall *)(SC_HANDLE,DWORD,LPVOID))
+		GetProcAddress(nt->hAdvapi32, "ChangeServiceConfig2W");
+	nt->CloseServiceHandle =
+		(BOOL (__stdcall *)(SC_HANDLE))
+		GetProcAddress(nt->hAdvapi32, "CloseServiceHandle");
+	nt->OpenService =
+		(SC_HANDLE (__stdcall *)(SC_HANDLE,LPCTSTR,DWORD))
+		GetProcAddress(nt->hAdvapi32, "OpenServiceA");
+	nt->QueryServiceStatus =
+		(BOOL (__stdcall *)(SC_HANDLE,LPSERVICE_STATUS))
+		GetProcAddress(nt->hAdvapi32, "QueryServiceStatus");
+	nt->StartService =
+		(BOOL (__stdcall *)(SC_HANDLE,DWORD,LPCTSTR))
+		GetProcAddress(nt->hAdvapi32, "StartServiceA");
+	nt->ControlService =
+		(BOOL (__stdcall *)(SC_HANDLE,DWORD,LPSERVICE_STATUS))
+		GetProcAddress(nt->hAdvapi32, "ControlService");
+	nt->SetServiceStatus =
+		(BOOL (__stdcall *)(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS))
+		GetProcAddress(nt->hAdvapi32, "SetServiceStatus");
+	nt->RegisterServiceCtrlHandler =
+		(SERVICE_STATUS_HANDLE (__stdcall *)(LPCTSTR,LPHANDLER_FUNCTION))
+		GetProcAddress(nt->hAdvapi32, "RegisterServiceCtrlHandlerW");
+	nt->StartServiceCtrlDispatcher =
+		(BOOL (__stdcall *)(const LPSERVICE_TABLE_ENTRY))
+		GetProcAddress(nt->hAdvapi32, "StartServiceCtrlDispatcherW");
+	nt->DeleteService =
+		(BOOL (__stdcall *)(SC_HANDLE))
+		GetProcAddress(nt->hAdvapi32, "DeleteService");
+	nt->RegisterEventSourceW =
+		(HANDLE (__stdcall *)(LPCWSTR,LPCWSTR))
+		GetProcAddress(nt->hAdvapi32, "RegisterEventSourceW");
+	nt->ReportEventW =
+		(BOOL (__stdcall *)(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR *,LPVOID))
+		GetProcAddress(nt->hAdvapi32, "ReportEventW");
+	nt->DeregisterEventSource =
+		(BOOL (__stdcall *)(HANDLE))
+		GetProcAddress(nt->hAdvapi32, "DeregisterEventSource");
+	nt->Wow64DisableWow64FsRedirection =
+		(BOOL (__stdcall *)(void **))
+		GetProcAddress(nt->hKernel32, "Wow64DisableWow64FsRedirection");
+	nt->Wow64EnableWow64FsRedirection =
+		(BOOLEAN (__stdcall *)(BOOLEAN))
+		GetProcAddress(nt->hKernel32, "Wow64EnableWow64FsRedirection");
+	nt->Wow64RevertWow64FsRedirection =
+		(BOOL (__stdcall *)(void *))
+		GetProcAddress(nt->hKernel32, "Wow64RevertWow64FsRedirection");
+
+	if (nt->hPsApi != NULL)
+	{
+		// プロセス系 API
+		nt->EnumProcesses =
+			(BOOL (__stdcall *)(DWORD *,DWORD,DWORD *))
+			GetProcAddress(nt->hPsApi, "EnumProcesses");
+
+		nt->EnumProcessModules =
+			(BOOL (__stdcall *)(HANDLE,HMODULE * ,DWORD,DWORD *))
+			GetProcAddress(nt->hPsApi, "EnumProcessModules");
+
+		nt->GetModuleFileNameExA =
+			(DWORD (__stdcall *)(HANDLE,HMODULE,LPSTR,DWORD))
+			GetProcAddress(nt->hPsApi, "GetModuleFileNameExA");
+
+		nt->GetModuleFileNameExW =
+			(DWORD (__stdcall *)(HANDLE,HMODULE,LPWSTR,DWORD))
+			GetProcAddress(nt->hPsApi, "GetModuleFileNameExW");
+	}
+
+	// レジストリ系 API
+	nt->RegDeleteKeyExA =
+		(LONG (__stdcall *)(HKEY,LPCTSTR,REGSAM,DWORD))
+		GetProcAddress(nt->hAdvapi32, "RegDeleteKeyExA");
+
+	// セキュリティ系 API
+	if (nt->hSecur32 != NULL)
+	{
+		nt->GetUserNameExA =
+			(BOOL (__stdcall *)(EXTENDED_NAME_FORMAT,LPSTR,PULONG))
+			GetProcAddress(nt->hSecur32, "GetUserNameExA");
+
+		nt->GetUserNameExW =
+			(BOOL (__stdcall *)(EXTENDED_NAME_FORMAT,LPWSTR,PULONG))
+			GetProcAddress(nt->hSecur32, "GetUserNameExW");
+	}
+
+	// デスクトップ系 API
+	if (nt->hUser32 != NULL)
+	{
+		nt->SwitchDesktop =
+			(BOOL (__stdcall *)(HDESK))
+			GetProcAddress(nt->hUser32, "SwitchDesktop");
+		nt->OpenDesktopA =
+			(HDESK (__stdcall *)(LPTSTR,DWORD,BOOL,ACCESS_MASK))
+			GetProcAddress(nt->hUser32, "OpenDesktopA");
+		nt->CloseDesktop =
+			(BOOL (__stdcall *)(HDESK))
+			GetProcAddress(nt->hUser32, "CloseDesktop");
+	}
+
+	// デバッグ系 API
+	if (nt->hDbgHelp != NULL)
+	{
+		nt->MiniDumpWriteDump =
+			(BOOL (__stdcall *)(HANDLE,DWORD,HANDLE,MINIDUMP_TYPE,PMINIDUMP_EXCEPTION_INFORMATION,PMINIDUMP_USER_STREAM_INFORMATION,PMINIDUMP_CALLBACK_INFORMATION))
+			GetProcAddress(nt->hDbgHelp, "MiniDumpWriteDump");
+	}
+
+	return nt;
+}
+
+// NT 系関数の解放
+void MsFreeNtApiFunctions(NT_API *nt)
+{
+	// 引数チェック
+	if (nt == NULL)
+	{
+		return;
+	}
+
+	if (nt->hSecur32 != NULL)
+	{
+		FreeLibrary(nt->hSecur32);
+	}
+
+	if (nt->hNewDev != NULL)
+	{
+		FreeLibrary(nt->hSetupApi);
+		FreeLibrary(nt->hNewDev);
+	}
+
+	FreeLibrary(nt->hAdvapi32);
+
+	FreeLibrary(nt->hShell32);
+
+	if (nt->hWtsApi32 != NULL)
+	{
+		FreeLibrary(nt->hWtsApi32);
+	}
+
+	if (nt->hPsApi != NULL)
+	{
+		FreeLibrary(nt->hPsApi);
+	}
+
+	if (nt->hUser32 != NULL)
+	{
+		FreeLibrary(nt->hUser32);
+	}
+
+	if (nt->hDbgHelp != NULL)
+	{
+		FreeLibrary(nt->hDbgHelp);
+	}
+
+	FreeLibrary(nt->hKernel32);
+
+	Free(nt);
+}
+
+// 64 bit アプリケーションのために 32 bit レジストリキーへのアクセスを強制するアクセスマスクを生成する
+DWORD MsRegAccessMaskFor64Bit(bool force32bit)
+{
+	return MsRegAccessMaskFor64BitEx(force32bit, false);
+}
+DWORD MsRegAccessMaskFor64BitEx(bool force32bit, bool force64bit)
+{
+	if (MsIs64BitWindows() == false)
+	{
+		return 0;
+	}
+	if (force32bit)
+	{
+		return KEY_WOW64_32KEY;
+	}
+	if (force64bit)
+	{
+		return KEY_WOW64_64KEY;
+	}
+
+	return 0;
+}
+
+// 値の削除
+bool MsRegDeleteValue(UINT root, char *keyname, char *valuename)
+{
+	return MsRegDeleteValueEx(root, keyname, valuename, false);
+}
+bool MsRegDeleteValueEx(UINT root, char *keyname, char *valuename, bool force32bit)
+{
+	return MsRegDeleteValueEx2(root, keyname, valuename, force32bit, false);
+}
+bool MsRegDeleteValueEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	bool ret;
+	// 引数チェック
+	if (keyname == NULL)
+	{
+		return false;
+	}
+
+	if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	if (RegDeleteValue(h, valuename) != ERROR_SUCCESS)
+	{
+		ret = false;
+	}
+	else
+	{
+		ret = true;
+	}
+
+	RegCloseKey(h);
+
+	return ret;
+}
+
+// キーの削除
+bool MsRegDeleteKey(UINT root, char *keyname)
+{
+	return MsRegDeleteKeyEx(root, keyname, false);
+}
+bool MsRegDeleteKeyEx(UINT root, char *keyname, bool force32bit)
+{
+	return MsRegDeleteKeyEx2(root, keyname, force32bit, false);
+}
+bool MsRegDeleteKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit)
+{
+	// 引数チェック
+	if (keyname == NULL)
+	{
+		return false;
+	}
+
+	if (MsIsNt() && ms->nt->RegDeleteKeyExA != NULL)
+	{
+		if (ms->nt->RegDeleteKeyExA(MsGetRootKeyFromInt(root), keyname, MsRegAccessMaskFor64BitEx(force32bit, force64bit), 0) != ERROR_SUCCESS)
+		{
+			return false;
+		}
+	}
+	else
+	{
+		if (RegDeleteKey(MsGetRootKeyFromInt(root), keyname) != ERROR_SUCCESS)
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// 値の列挙
+TOKEN_LIST *MsRegEnumValue(UINT root, char *keyname)
+{
+	return MsRegEnumValueEx(root, keyname, false);
+}
+TOKEN_LIST *MsRegEnumValueEx(UINT root, char *keyname, bool force32bit)
+{
+	return MsRegEnumValueEx2(root, keyname, force32bit, false);
+}
+TOKEN_LIST *MsRegEnumValueEx2(UINT root, char *keyname, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	UINT i;
+	TOKEN_LIST *t;
+	LIST *o;
+
+	if (keyname == NULL)
+	{
+		h = MsGetRootKeyFromInt(root);
+	}
+	else
+	{
+		if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+		{
+			return NULL;
+		}
+	}
+
+	o = NewListFast(CompareStr);
+
+	for (i = 0;;i++)
+	{
+		char tmp[MAX_SIZE];
+		UINT ret;
+		UINT size = sizeof(tmp);
+
+		Zero(tmp, sizeof(tmp));
+		ret = RegEnumValue(h, i, tmp, &size, NULL, NULL, NULL, NULL);
+		if (ret == ERROR_NO_MORE_ITEMS)
+		{
+			break;
+		}
+		else if (ret != ERROR_SUCCESS)
+		{
+			break;
+		}
+
+		Add(o, CopyStr(tmp));
+	}
+
+	Sort(o);
+
+	t = ZeroMalloc(sizeof(TOKEN_LIST));
+	t->NumTokens = LIST_NUM(o);
+	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		t->Token[i] = LIST_DATA(o, i);
+	}
+
+	ReleaseList(o);
+
+	if (keyname != NULL)
+	{
+		RegCloseKey(h);
+	}
+
+	return t;
+}
+
+// キーの列挙
+TOKEN_LIST *MsRegEnumKey(UINT root, char *keyname)
+{
+	return MsRegEnumKeyEx(root, keyname, false);
+}
+TOKEN_LIST *MsRegEnumKeyEx(UINT root, char *keyname, bool force32bit)
+{
+	return MsRegEnumKeyEx2(root, keyname, force32bit, false);
+}
+TOKEN_LIST *MsRegEnumKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	UINT i;
+	TOKEN_LIST *t;
+	LIST *o;
+
+	if (keyname == NULL)
+	{
+		h = MsGetRootKeyFromInt(root);
+	}
+	else
+	{
+		if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+		{
+			return NULL;
+		}
+	}
+
+	o = NewListFast(CompareStr);
+
+	for (i = 0;;i++)
+	{
+		char tmp[MAX_SIZE];
+		UINT ret;
+		UINT size = sizeof(tmp);
+		FILETIME ft;
+
+		Zero(tmp, sizeof(tmp));
+		ret = RegEnumKeyEx(h, i, tmp, &size, NULL, NULL, NULL, &ft);
+		if (ret == ERROR_NO_MORE_ITEMS)
+		{
+			break;
+		}
+		else if (ret != ERROR_SUCCESS)
+		{
+			break;
+		}
+
+		Add(o, CopyStr(tmp));
+	}
+
+	Sort(o);
+
+	t = ZeroMalloc(sizeof(TOKEN_LIST));
+	t->NumTokens = LIST_NUM(o);
+	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		t->Token[i] = LIST_DATA(o, i);
+	}
+
+	ReleaseList(o);
+
+	if (keyname != NULL)
+	{
+		RegCloseKey(h);
+	}
+
+	return t;
+}
+
+// バイナリデータを設定する
+bool MsRegWriteBin(UINT root, char *keyname, char *valuename, void *data, UINT size)
+{
+	return MsRegWriteBinEx(root, keyname, valuename, data, size, false);
+}
+bool MsRegWriteBinEx(UINT root, char *keyname, char *valuename, void *data, UINT size, bool force32bit)
+{
+	return MsRegWriteBinEx2(root, keyname, valuename, data, size, force32bit, false);
+}
+bool MsRegWriteBinEx2(UINT root, char *keyname, char *valuename, void *data, UINT size, bool force32bit, bool force64bit)
+{
+	// 引数チェック
+	if (keyname == NULL || (size != 0 && data == NULL))
+	{
+		return false;
+	}
+
+	return MsRegWriteValueEx2(root, keyname, valuename, REG_BINARY, data, size, force32bit, force64bit);
+}
+
+// 整数値を設定する
+bool MsRegWriteInt(UINT root, char *keyname, char *valuename, UINT value)
+{
+	return MsRegWriteIntEx(root, keyname, valuename, value, false);
+}
+bool MsRegWriteIntEx(UINT root, char *keyname, char *valuename, UINT value, bool force32bit)
+{
+	return MsRegWriteIntEx2(root, keyname, valuename, value, force32bit, false);
+}
+bool MsRegWriteIntEx2(UINT root, char *keyname, char *valuename, UINT value, bool force32bit, bool force64bit)
+{
+	// 引数チェック
+	if (keyname == NULL)
+	{
+		return false;
+	}
+
+	// エンディアン補正
+	if (IsBigEndian())
+	{
+		value = Swap32(value);
+	}
+
+	return MsRegWriteValueEx2(root, keyname, valuename, REG_DWORD_LITTLE_ENDIAN, &value, sizeof(UINT), force32bit, force64bit);
+}
+
+// 文字列を設定する
+bool MsRegWriteStrExpand(UINT root, char *keyname, char *valuename, char *str)
+{
+	return MsRegWriteStrExpandEx(root, keyname, valuename, str, false);
+}
+bool MsRegWriteStrExpandEx(UINT root, char *keyname, char *valuename, char *str, bool force32bit)
+{
+	return MsRegWriteStrExpandEx2(root, keyname, valuename, str, force32bit, false);
+}
+bool MsRegWriteStrExpandEx2(UINT root, char *keyname, char *valuename, char *str, bool force32bit, bool force64bit)
+{
+	// 引数チェック
+	if (keyname == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	return MsRegWriteValueEx2(root, keyname, valuename, REG_EXPAND_SZ, str, StrSize(str), force32bit, force64bit);
+}
+bool MsRegWriteStrExpandW(UINT root, char *keyname, char *valuename, wchar_t *str)
+{
+	return MsRegWriteStrExpandExW(root, keyname, valuename, str, false);
+}
+bool MsRegWriteStrExpandExW(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit)
+{
+	return MsRegWriteStrExpandEx2W(root, keyname, valuename, str, force32bit, false);
+}
+bool MsRegWriteStrExpandEx2W(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit, bool force64bit)
+{
+	// 引数チェック
+	if (keyname == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	return MsRegWriteValueEx2W(root, keyname, valuename, REG_EXPAND_SZ, str, UniStrSize(str), force32bit, force64bit);
+}
+
+bool MsRegWriteStr(UINT root, char *keyname, char *valuename, char *str)
+{
+	return MsRegWriteStrEx(root, keyname, valuename, str, false);
+}
+bool MsRegWriteStrEx(UINT root, char *keyname, char *valuename, char *str, bool force32bit)
+{
+	return MsRegWriteStrEx2(root, keyname, valuename, str, force32bit, false);
+}
+bool MsRegWriteStrEx2(UINT root, char *keyname, char *valuename, char *str, bool force32bit, bool force64bit)
+{
+	// 引数チェック
+	if (keyname == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	return MsRegWriteValueEx2(root, keyname, valuename, REG_SZ, str, StrSize(str), force32bit, force64bit);
+}
+bool MsRegWriteStrW(UINT root, char *keyname, char *valuename, wchar_t *str)
+{
+	return MsRegWriteStrExW(root, keyname, valuename, str, false);
+}
+bool MsRegWriteStrExW(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit)
+{
+	return MsRegWriteStrEx2W(root, keyname, valuename, str, force32bit, false);
+}
+bool MsRegWriteStrEx2W(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit, bool force64bit)
+{
+	// 引数チェック
+	if (keyname == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	return MsRegWriteValueEx2W(root, keyname, valuename, REG_SZ, str, UniStrSize(str), force32bit, force64bit);
+}
+
+// 値を設定する
+bool MsRegWriteValue(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size)
+{
+	return MsRegWriteValueEx(root, keyname, valuename, type, data, size, false);
+}
+bool MsRegWriteValueEx(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit)
+{
+	return MsRegWriteValueEx2(root, keyname, valuename, type, data, size, force32bit, false);
+}
+bool MsRegWriteValueEx2(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	// 引数チェック
+	if (keyname == NULL || (size != 0 && data == NULL))
+	{
+		return false;
+	}
+
+	// キーを作成する
+	MsRegNewKeyEx2(root, keyname, force32bit, force64bit);
+
+	// キーを開く
+	if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	// 値を書き込む
+	if (RegSetValueEx(h, valuename, 0, type, data, size) != ERROR_SUCCESS)
+	{
+		RegCloseKey(h);
+		return false;
+	}
+
+	// キーを閉じる
+	RegCloseKey(h);
+
+	return true;
+}
+bool MsRegWriteValueW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size)
+{
+	return MsRegWriteValueExW(root, keyname, valuename, type, data, size, false);
+}
+bool MsRegWriteValueExW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit)
+{
+	return MsRegWriteValueEx2W(root, keyname, valuename, type, data, size, force32bit, false);
+}
+bool MsRegWriteValueEx2W(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	wchar_t valuename_w[MAX_SIZE];
+	// 引数チェック
+	if (keyname == NULL || (size != 0 && data == NULL))
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		UINT size_a;
+		void *data_a;
+		bool ret;
+
+		if (type == REG_SZ || type == REG_MULTI_SZ || type == REG_EXPAND_SZ)
+		{
+			data_a = CopyUniToStr(data);
+			size_a = StrSize(data_a);
+		}
+		else
+		{
+			data_a = Clone(data, size);
+			size_a = size;
+		}
+
+		ret = MsRegWriteValueEx2(root, keyname, valuename, type, data_a, size_a, force32bit, force64bit);
+
+		Free(data_a);
+
+		return ret;
+	}
+
+	StrToUni(valuename_w, sizeof(valuename_w), valuename);
+
+	// キーを作成する
+	MsRegNewKeyEx2(root, keyname, force32bit, force64bit);
+
+	// キーを開く
+	if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	// 値を書き込む
+	if (RegSetValueExW(h, valuename_w, 0, type, data, size) != ERROR_SUCCESS)
+	{
+		RegCloseKey(h);
+		return false;
+	}
+
+	// キーを閉じる
+	RegCloseKey(h);
+
+	return true;
+}
+
+// バイナリデータを取得する
+BUF *MsRegReadBin(UINT root, char *keyname, char *valuename)
+{
+	return MsRegReadBinEx(root, keyname, valuename, false);
+}
+BUF *MsRegReadBinEx(UINT root, char *keyname, char *valuename, bool force32bit)
+{
+	return MsRegReadBinEx2(root, keyname, valuename, force32bit, false);
+}
+BUF *MsRegReadBinEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
+{
+	char *ret;
+	UINT type, size;
+	BUF *b;
+	// 引数チェック
+	if (keyname == NULL || valuename == NULL)
+	{
+		return 0;
+	}
+
+	// 値を読み込む
+	if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
+	{
+		return 0;
+	}
+
+	b = NewBuf();
+
+	WriteBuf(b, ret, size);
+	SeekBuf(b, 0, 0);
+
+	Free(ret);
+
+	return b;
+}
+
+// 整数値を取得する
+UINT MsRegReadInt(UINT root, char *keyname, char *valuename)
+{
+	return MsRegReadIntEx(root, keyname, valuename, false);
+}
+UINT MsRegReadIntEx(UINT root, char *keyname, char *valuename, bool force32bit)
+{
+	return MsRegReadIntEx2(root, keyname, valuename, force32bit, false);
+}
+UINT MsRegReadIntEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
+{
+	char *ret;
+	UINT type, size;
+	UINT value;
+	// 引数チェック
+	if (keyname == NULL || valuename == NULL)
+	{
+		return 0;
+	}
+
+	// 値を読み込む
+	if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
+	{
+		return 0;
+	}
+
+	// 種類をチェックする
+	if (type != REG_DWORD_LITTLE_ENDIAN && type != REG_DWORD_BIG_ENDIAN)
+	{
+		// DWORD 以外である
+		Free(ret);
+		return 0;
+	}
+
+	// サイズをチェックする
+	if (size != sizeof(UINT))
+	{
+		Free(ret);
+		return 0;
+	}
+
+	Copy(&value, ret, sizeof(UINT));
+
+	Free(ret);
+
+	// エンディアン変換
+	if (IsLittleEndian())
+	{
+#ifdef	REG_DWORD_BIG_ENDIAN
+		if (type == REG_DWORD_BIG_ENDIAN)
+		{
+			value = Swap32(value);
+		}
+#endif	// REG_DWORD_BIG_ENDIAN
+	}
+	else
+	{
+#ifdef	REG_DWORD_LITTLE_ENDIAN_FLAG
+		if (type == REG_DWORD_LITTLE_ENDIAN_FLAG)
+		{
+			value = Swap32(value);
+		}
+#endif	// REG_DWORD_LITTLE_ENDIAN_FLAG
+	}
+
+	return value;
+}
+
+// 文字列リストを取得する
+LIST *MsRegReadStrList(UINT root, char *keyname, char *valuename)
+{
+	return MsRegReadStrListEx(root, keyname, valuename, false);
+}
+LIST *MsRegReadStrListEx(UINT root, char *keyname, char *valuename, bool force32bit)
+{
+	return MsRegReadStrListEx2(root, keyname, valuename, force32bit, false);
+}
+LIST *MsRegReadStrListEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
+{
+	LIST *o;
+	char *ret;
+	UINT type, size;
+	// 引数チェック
+	if (keyname == NULL || valuename == NULL)
+	{
+		return NULL;
+	}
+
+	// 値を読み込む
+	if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
+	{
+		return NULL;
+	}
+
+	// 種類をチェックする
+	if (type != REG_MULTI_SZ)
+	{
+		// 文字列リスト以外である
+		Free(ret);
+		return NULL;
+	}
+
+	if (size < 2)
+	{
+		// サイズ不正
+		Free(ret);
+		return NULL;
+	}
+
+	if (ret[size - 1] != 0)
+	{
+		// データ不正
+		Free(ret);
+		return NULL;
+	}
+
+	// リスト作成
+	o = StrToStrList(ret, size);
+
+	Free(ret);
+
+	return o;
+}
+
+// 文字列を取得する
+char *MsRegReadStr(UINT root, char *keyname, char *valuename)
+{
+	return MsRegReadStrEx(root, keyname, valuename, false);
+}
+char *MsRegReadStrEx(UINT root, char *keyname, char *valuename, bool force32bit)
+{
+	return MsRegReadStrEx2(root, keyname, valuename, force32bit, false);
+}
+char *MsRegReadStrEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
+{
+	char *ret;
+	UINT type, size;
+	// 引数チェック
+	if (keyname == NULL || valuename == NULL)
+	{
+		return NULL;
+	}
+
+	// 値を読み込む
+	if (MsRegReadValueEx2(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
+	{
+		return NULL;
+	}
+
+	// 種類をチェックする
+	if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ)
+	{
+		// 文字列以外である
+		Free(ret);
+
+		if (type == REG_MULTI_SZ)
+		{
+			// 文字列リストである
+			LIST *o = MsRegReadStrList(root, keyname, valuename);
+			if (o != NULL)
+			{
+				if (LIST_NUM(o) >= 1)
+				{
+					ret = CopyStr(LIST_DATA(o, 0));
+					FreeStrList(o);
+					return ret;
+				}
+			}
+		}
+		return NULL;
+	}
+
+	if (size == 0)
+	{
+		// サイズ不正
+		Free(ret);
+
+		return CopyStr("");
+	}
+
+	if (ret[size - 1] != 0)
+	{
+		// データ不正
+		Free(ret);
+		return NULL;
+	}
+
+	return ret;
+}
+wchar_t *MsRegReadStrW(UINT root, char *keyname, char *valuename)
+{
+	return MsRegReadStrExW(root, keyname, valuename, false);
+}
+wchar_t *MsRegReadStrExW(UINT root, char *keyname, char *valuename, bool force32bit)
+{
+	return MsRegReadStrEx2W(root, keyname, valuename, force32bit, false);
+}
+wchar_t *MsRegReadStrEx2W(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
+{
+	wchar_t *ret;
+	UINT type, size;
+	// 引数チェック
+	if (keyname == NULL || valuename == NULL)
+	{
+		return NULL;
+	}
+
+	// 値を読み込む
+	if (MsRegReadValueEx2W(root, keyname, valuename, &ret, &type, &size, force32bit, force64bit) == false)
+	{
+		return NULL;
+	}
+
+	// 種類をチェックする
+	if (type != REG_SZ && type != REG_EXPAND_SZ)
+	{
+		// 文字列以外である
+		Free(ret);
+
+		return NULL;
+	}
+
+	if (ret[size / sizeof(wchar_t) - 1] != 0)
+	{
+		// データ不正
+		Free(ret);
+		return NULL;
+	}
+
+	return ret;
+}
+
+// 値を読み込む
+bool MsRegReadValue(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size)
+{
+	return MsRegReadValueEx(root, keyname, valuename, data, type, size, false);
+}
+bool MsRegReadValueEx(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit)
+{
+	return MsRegReadValueEx2(root, keyname, valuename, data, type, size, force32bit, false);
+}
+bool MsRegReadValueEx2(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	UINT ret;
+	// 引数チェック
+	if (keyname == NULL || data == NULL || type == NULL || size == NULL)
+	{
+		return false;
+	}
+	*type = 0;
+	*size = 0;
+
+	// キーを開く
+	if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	// 値を開く
+	*data = ZeroMalloc(*size);
+	ret = RegQueryValueEx(h, valuename, 0, type, *data, size);
+
+	if (ret == ERROR_SUCCESS)
+	{
+		// 読み取り完了
+		RegCloseKey(h);
+		return true;
+	}
+
+	if (ret != ERROR_MORE_DATA)
+	{
+		// 変なエラーが発生した
+		Free(*data);
+		*data = NULL;
+		RegCloseKey(h);
+		return false;
+	}
+
+	// メモリを再確保してデータを取得
+	*data = ReAlloc(*data, *size);
+	ret = RegQueryValueEx(h, valuename, 0, type, *data, size);
+	if (ret != ERROR_SUCCESS)
+	{
+		// エラー発生
+		Free(*data);
+		*data = NULL;
+		RegCloseKey(h);
+	}
+
+	RegCloseKey(h);
+
+	return true;
+}
+bool MsRegReadValueW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size)
+{
+	return MsRegReadValueExW(root, keyname, valuename, data, type, size, false);
+}
+bool MsRegReadValueExW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit)
+{
+	return MsRegReadValueEx2W(root, keyname, valuename, data, type, size, force32bit, false);
+}
+bool MsRegReadValueEx2W(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	UINT ret;
+	wchar_t valuename_w[MAX_SIZE];
+	// 引数チェック
+	if (keyname == NULL || data == NULL || type == NULL || size == NULL)
+	{
+		return false;
+	}
+	*type = 0;
+	*size = 0;
+
+	if (IsNt() == false)
+	{
+		bool ret;
+		void *data_a = NULL;
+		UINT type_a = 0, size_a = 0;
+
+		ret = MsRegReadValueEx2(root, keyname, valuename, &data_a, &type_a, &size_a, force32bit, force64bit);
+
+		if (ret != false)
+		{
+			if (type_a == REG_SZ || type_a == REG_MULTI_SZ || type_a == REG_EXPAND_SZ)
+			{
+				*data = CopyStrToUni(data_a);
+				Free(data_a);
+
+				size_a = UniStrSize(*data);
+			}
+			else
+			{
+				*data = data_a;
+			}
+
+			*type = type_a;
+			*size = size_a;
+		}
+
+		return ret;
+	}
+
+	StrToUni(valuename_w, sizeof(valuename_w), valuename);
+
+	// キーを開く
+	if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	// 値を開く
+	*data = ZeroMalloc(*size);
+	ret = RegQueryValueExW(h, valuename_w, 0, type, *data, size);
+
+	if (ret == ERROR_SUCCESS)
+	{
+		// 読み取り完了
+		RegCloseKey(h);
+		return true;
+	}
+
+	if (ret != ERROR_MORE_DATA)
+	{
+		// 変なエラーが発生した
+		Free(*data);
+		*data = NULL;
+		RegCloseKey(h);
+		return false;
+	}
+
+	// メモリを再確保してデータを取得
+	*data = ReAlloc(*data, *size);
+	ret = RegQueryValueExW(h, valuename_w, 0, type, *data, size);
+	if (ret != ERROR_SUCCESS)
+	{
+		// エラー発生
+		Free(*data);
+		*data = NULL;
+		RegCloseKey(h);
+	}
+
+	RegCloseKey(h);
+
+	return true;
+}
+
+// 値の種類とサイズを取得する
+bool MsRegGetValueTypeAndSize(UINT root, char *keyname, char *valuename, UINT *type, UINT *size)
+{
+	return MsRegGetValueTypeAndSizeEx(root, keyname, valuename, type, size, false);
+}
+bool MsRegGetValueTypeAndSizeEx(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit)
+{
+	return MsRegGetValueTypeAndSizeEx2(root, keyname, valuename, type, size, force32bit, false);
+}
+bool MsRegGetValueTypeAndSizeEx2(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	UINT ret;
+	// 引数チェック
+	if (keyname == NULL)
+	{
+		return false;
+	}
+	if (type != NULL)
+	{
+		*type = 0;
+	}
+	if (size != NULL)
+	{
+		*size = 0;
+	}
+
+	// キーを開く
+	if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	// 値を開く
+	ret = RegQueryValueEx(h, valuename, 0, type, NULL, size);
+
+	if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
+	{
+		RegCloseKey(h);
+		return true;
+	}
+
+	RegCloseKey(h);
+
+	return false;
+}
+bool MsRegGetValueTypeAndSizeW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size)
+{
+	return MsRegGetValueTypeAndSizeExW(root, keyname, valuename, type, size, false);
+}
+bool MsRegGetValueTypeAndSizeExW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit)
+{
+	return MsRegGetValueTypeAndSizeEx2W(root, keyname, valuename, type, size, force32bit, false);
+}
+bool MsRegGetValueTypeAndSizeEx2W(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	UINT ret;
+	wchar_t valuename_w[MAX_SIZE];
+	// 引数チェック
+	if (keyname == NULL)
+	{
+		return false;
+	}
+	if (type != NULL)
+	{
+		*type = 0;
+	}
+	if (size != NULL)
+	{
+		*size = 0;
+	}
+	if (IsNt() == false)
+	{
+		UINT type_a = 0;
+		UINT size_a = 0;
+
+		bool ret = MsRegGetValueTypeAndSizeEx2(root, keyname, valuename, &type_a, &size_a, force32bit, force64bit);
+
+		if (type_a == REG_SZ || type_a == REG_MULTI_SZ || type_a == REG_EXPAND_SZ)
+		{
+			size_a = size_a * sizeof(wchar_t);
+		}
+
+		if (type != NULL)
+		{
+			*type = type_a;
+		}
+
+		if (size != NULL)
+		{
+			*size = size_a;
+		}
+
+		return ret;
+	}
+
+	StrToUni(valuename_w, sizeof(valuename_w), valuename);
+
+	// キーを開く
+	if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	// 値を開く
+	ret = RegQueryValueExW(h, valuename_w, 0, type, NULL, size);
+
+	if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
+	{
+		RegCloseKey(h);
+		return true;
+	}
+
+	RegCloseKey(h);
+
+	return false;
+}
+
+// 指定された値がレジストリに存在するかどうか確認する
+bool MsRegIsValue(UINT root, char *keyname, char *valuename)
+{
+	return MsRegIsValueEx(root, keyname, valuename, false);
+}
+bool MsRegIsValueEx(UINT root, char *keyname, char *valuename, bool force32bit)
+{
+	return MsRegIsValueEx2(root, keyname, valuename, force32bit, false);
+}
+bool MsRegIsValueEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	UINT type, size;
+	UINT ret;
+	// 引数チェック
+	if (keyname == NULL)
+	{
+		return false;
+	}
+
+	// キーを開く
+	if (RegOpenKeyEx(MsGetRootKeyFromInt(root), keyname, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	// 値を開く
+	size = 0;
+	ret = RegQueryValueEx(h, valuename, 0, &type, NULL, &size);
+
+	if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
+	{
+		RegCloseKey(h);
+		return true;
+	}
+
+	RegCloseKey(h);
+
+	return false;
+}
+
+// レジストリにキーを作成する
+bool MsRegNewKey(UINT root, char *keyname)
+{
+	return MsRegNewKeyEx(root, keyname, false);
+}
+bool MsRegNewKeyEx(UINT root, char *keyname, bool force32bit)
+{
+	return MsRegNewKeyEx2(root, keyname, force32bit, false);
+}
+bool MsRegNewKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	// 引数チェック
+	if (keyname == NULL)
+	{
+		return false;
+	}
+
+	// キーが存在するかどうか確認する
+	if (MsRegIsKeyEx2(root, keyname, force32bit, force64bit))
+	{
+		// すでに存在している
+		return true;
+	}
+
+	// キーを作成する
+	if (RegCreateKeyEx(MsGetRootKeyFromInt(root), keyname, 0, NULL, REG_OPTION_NON_VOLATILE,
+		KEY_ALL_ACCESS | MsRegAccessMaskFor64BitEx(force32bit, force64bit), NULL, &h, NULL) != ERROR_SUCCESS)
+	{
+		// 失敗
+		return false;
+	}
+
+	RegCloseKey(h);
+
+	return true;
+}
+
+// 指定されたキーがレジストリに存在するかどうか確認する
+bool MsRegIsKey(UINT root, char *name)
+{
+	return MsRegIsKeyEx(root, name, false);
+}
+bool MsRegIsKeyEx(UINT root, char *name, bool force32bit)
+{
+	return MsRegIsKeyEx2(root, name, force32bit, false);
+}
+bool MsRegIsKeyEx2(UINT root, char *name, bool force32bit, bool force64bit)
+{
+	HKEY h;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (RegOpenKeyEx(MsGetRootKeyFromInt(root), name, 0, KEY_READ | MsRegAccessMaskFor64BitEx(force32bit, force64bit), &h) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	RegCloseKey(h);
+
+	return true;
+}
+
+// ルートキーハンドルの取得
+HKEY MsGetRootKeyFromInt(UINT root)
+{
+	switch (root)
+	{
+	case REG_CLASSES_ROOT:
+		return HKEY_CLASSES_ROOT;
+
+	case REG_LOCAL_MACHINE:
+		return HKEY_LOCAL_MACHINE;
+
+	case REG_CURRENT_USER:
+		return HKEY_CURRENT_USER;
+
+	case REG_USERS:
+		return HKEY_USERS;
+	}
+
+	return NULL;
+}
+
+// コマンドライン文字列から実行ファイル名の部分をカットする (Unicode 版)
+wchar_t *MsCutExeNameFromUniCommandLine(wchar_t *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	if (str[0] != L'\"')
+	{
+		UINT i = UniSearchStrEx(str, L" ", 0, true);
+		if (i == INFINITE)
+		{
+			return str + UniStrLen(str);
+		}
+		else
+		{
+			return str + i + 1;
+		}
+	}
+	else
+	{
+		str++;
+		while (true)
+		{
+			if ((*str) == 0)
+			{
+				return str + UniStrLen(str);
+			}
+			if ((*str) == L'\"')
+			{
+				break;
+			}
+			str++;
+		}
+
+		while (true)
+		{
+			if ((*str) == 0)
+			{
+				return str + UniStrLen(str);
+			}
+			if ((*str) == L' ')
+			{
+				return str + 1;
+			}
+			str++;
+		}
+	}
+}
+
+// コマンドライン文字列から実行ファイル名の部分をカットする
+char *MsCutExeNameFromCommandLine(char *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	if (str[0] != '\"')
+	{
+		UINT i = SearchStrEx(str, " ", 0, true);
+		if (i == INFINITE)
+		{
+			return str + StrLen(str);
+		}
+		else
+		{
+			return str + i + 1;
+		}
+	}
+	else
+	{
+		str++;
+		while (true)
+		{
+			if ((*str) == 0)
+			{
+				return str + StrLen(str);
+			}
+			if ((*str) == '\"')
+			{
+				break;
+			}
+			str++;
+		}
+
+		while (true)
+		{
+			if ((*str) == 0)
+			{
+				return str + StrLen(str);
+			}
+			if ((*str) == ' ')
+			{
+				return str + 1;
+			}
+			str++;
+		}
+	}
+}
+
+// プロセスハンドルの取得
+void *MsGetCurrentProcess()
+{
+	return ms->hCurrentProcess;
+}
+
+// プロセス ID の取得
+UINT MsGetCurrentProcessId()
+{
+	return ms->CurrentProcessId;
+}
+
+// EXE ファイル名の取得
+char *MsGetExeFileName()
+{
+	return ms == NULL ? "Unknown" : ms->ExeFileName;
+}
+
+// EXE ファイルが置いてあるディレクトリ名の取得
+char *MsGetExeDirName()
+{
+	return ms->ExeFileDir;
+}
+wchar_t *MsGetExeDirNameW()
+{
+	return ms->ExeFileDirW;
+}
+
+// 特殊なディレクトリ名の取得
+char *MsGetSpecialDir(int id)
+{
+	LPITEMIDLIST t = NULL;
+	char tmp[MAX_PATH];
+
+	if (SHGetSpecialFolderLocation(NULL, id, &t) != S_OK)
+	{
+		return CopyStr(ms->ExeFileDir);
+	}
+
+	if (SHGetPathFromIDList(t, tmp) == false)
+	{
+		return CopyStr(ms->ExeFileDir);
+	}
+
+	Win32NukuEn(tmp, sizeof(tmp), tmp);
+
+	return CopyStr(tmp);
+}
+wchar_t *MsGetSpecialDirW(int id)
+{
+	LPITEMIDLIST t = NULL;
+	wchar_t tmp[MAX_PATH];
+
+	if (IsNt() == false)
+	{
+		char *tmp = MsGetSpecialDir(id);
+		wchar_t *ret = CopyStrToUni(tmp);
+
+		Free(tmp);
+
+		return ret;
+	}
+
+	if (SHGetSpecialFolderLocation(NULL, id, &t) != S_OK)
+	{
+		return UniCopyStr(ms->ExeFileDirW);
+	}
+
+	if (SHGetPathFromIDListW(t, tmp) == false)
+	{
+		return UniCopyStr(ms->ExeFileDirW);
+	}
+
+	Win32NukuEnW(tmp, sizeof(tmp), tmp);
+
+	return UniCopyStr(tmp);
+}
+
+// 特殊なディレクトリをすべて取得する
+void MsGetSpecialDirs()
+{
+	char tmp[MAX_PATH];
+
+	// System32
+	GetSystemDirectory(tmp, sizeof(tmp));
+	Win32NukuEn(tmp, sizeof(tmp), tmp);
+	ms->System32Dir = CopyStr(tmp);
+	ms->System32DirW = CopyStrToUni(tmp);
+
+	// Windows ディレクトリは System32 ディレクトリの 1 つ上にある
+	Win32GetDirFromPath(tmp, sizeof(tmp), tmp);
+	Win32NukuEn(tmp, sizeof(tmp), tmp);
+	ms->WindowsDir = CopyStr(tmp);
+	ms->WindowsDirW = CopyStrToUni(tmp);
+
+	// Windows ディレクトリの下の Temp ディレクトリ
+	Format(tmp, sizeof(tmp), "%s\\Temp", ms->WindowsDir);
+	ms->WinTempDir = CopyStr(tmp);
+	ms->WinTempDirW = CopyStrToUni(tmp);
+	MsUniMakeDirEx(ms->WinTempDirW);
+
+	// システムドライブ
+	tmp[2] = 0;
+	ms->WindowsDrive = CopyStr(tmp);
+	ms->WindowsDriveW = CopyStrToUni(tmp);
+
+	// Temp
+	GetTempPath(MAX_PATH, tmp);
+	Win32NukuEn(tmp, sizeof(tmp), tmp);
+	ms->TempDir = CopyStr(tmp);
+
+	// Temp (Unicode) の取得
+	if (IsNt())
+	{
+		wchar_t tmp_w[MAX_PATH];
+
+		GetTempPathW(MAX_PATH, tmp_w);
+		Win32NukuEnW(tmp_w, sizeof(tmp_w), tmp_w);
+
+		ms->TempDirW = CopyUniStr(tmp_w);
+	}
+	else
+	{
+		ms->TempDirW = CopyStrToUni(tmp);
+	}
+	MakeDirExW(ms->TempDirW);
+	MakeDirEx(ms->TempDir);
+
+	// Program Files
+	ms->ProgramFilesDir = MsGetSpecialDir(CSIDL_PROGRAM_FILES);
+	if (StrCmpi(ms->ProgramFilesDir, ms->ExeFileDir) == 0)
+	{
+		char tmp[MAX_PATH];
+		Format(tmp, sizeof(tmp), "%s\\Program Files", ms->WindowsDrive);
+
+		Free(ms->ProgramFilesDir);
+		ms->ProgramFilesDir = CopyStr(tmp);
+	}
+
+	ms->ProgramFilesDirW = MsGetSpecialDirW(CSIDL_PROGRAM_FILES);
+	if (UniStrCmpi(ms->ProgramFilesDirW, ms->ExeFileDirW) == 0)
+	{
+		wchar_t tmp[MAX_PATH];
+		UniFormat(tmp, sizeof(tmp), L"%s\\Program Files", ms->WindowsDriveW);
+
+		Free(ms->ProgramFilesDirW);
+		ms->ProgramFilesDirW = UniCopyStr(tmp);
+	}
+
+	if (MsIsNt())
+	{
+		// 共通のスタートメニュー
+		ms->CommonStartMenuDir = MsGetSpecialDir(CSIDL_COMMON_STARTMENU);
+		ms->CommonStartMenuDirW = MsGetSpecialDirW(CSIDL_COMMON_STARTMENU);
+
+		// 共通のプログラム
+		ms->CommonProgramsDir = MsGetSpecialDir(CSIDL_COMMON_PROGRAMS);
+		ms->CommonProgramsDirW = MsGetSpecialDirW(CSIDL_COMMON_PROGRAMS);
+
+		// 共通のスタートアップ
+		ms->CommonStartupDir = MsGetSpecialDir(CSIDL_COMMON_STARTUP);
+		ms->CommonStartupDirW = MsGetSpecialDirW(CSIDL_COMMON_STARTUP);
+
+		// 共通のアプリケーションデータ
+		ms->CommonAppDataDir = MsGetSpecialDir(CSIDL_COMMON_APPDATA);
+		ms->CommonAppDataDirW = MsGetSpecialDirW(CSIDL_COMMON_APPDATA);
+
+		// 共通のデスクトップ
+		ms->CommonDesktopDir = MsGetSpecialDir(CSIDL_COMMON_DESKTOPDIRECTORY);
+		ms->CommonDesktopDirW = MsGetSpecialDirW(CSIDL_COMMON_DESKTOPDIRECTORY);
+
+		// Local Settings
+		ms->LocalAppDataDir = MsGetSpecialDir(CSIDL_LOCAL_APPDATA);
+		ms->LocalAppDataDirW = MsGetSpecialDirW(CSIDL_LOCAL_APPDATA);
+	}
+	else
+	{
+		// 個別のスタートメニュー
+		ms->PersonalStartMenuDir = MsGetSpecialDir(CSIDL_STARTMENU);
+		ms->CommonStartMenuDir = CopyStr(ms->PersonalStartMenuDir);
+		ms->PersonalStartMenuDirW = MsGetSpecialDirW(CSIDL_STARTMENU);
+		ms->CommonStartMenuDirW = CopyUniStr(ms->PersonalStartMenuDirW);
+
+		// 個別のプログラム
+		ms->PersonalProgramsDir = MsGetSpecialDir(CSIDL_PROGRAMS);
+		ms->CommonProgramsDir = CopyStr(ms->PersonalProgramsDir);
+		ms->PersonalProgramsDirW = MsGetSpecialDirW(CSIDL_PROGRAMS);
+		ms->CommonProgramsDirW = CopyUniStr(ms->PersonalProgramsDirW);
+
+		// 個別のスタートアップ
+		ms->PersonalStartupDir = MsGetSpecialDir(CSIDL_STARTUP);
+		ms->CommonStartupDir = CopyStr(ms->PersonalStartupDir);
+		ms->PersonalStartupDirW = MsGetSpecialDirW(CSIDL_STARTUP);
+		ms->CommonStartupDirW = CopyUniStr(ms->PersonalStartupDirW);
+
+		// 個別のアプリケーションデータ
+		ms->PersonalAppDataDir = MsGetSpecialDir(CSIDL_APPDATA);
+		ms->CommonAppDataDir = CopyStr(ms->PersonalAppDataDir);
+		ms->PersonalAppDataDirW = MsGetSpecialDirW(CSIDL_APPDATA);
+		ms->CommonAppDataDirW = CopyUniStr(ms->PersonalAppDataDirW);
+
+		// 個別のデスクトップ
+		ms->PersonalDesktopDir = MsGetSpecialDir(CSIDL_DESKTOP);
+		ms->CommonDesktopDir = CopyStr(ms->PersonalDesktopDir);
+		ms->PersonalDesktopDirW = MsGetSpecialDirW(CSIDL_DESKTOP);
+		ms->CommonDesktopDirW = CopyUniStr(ms->PersonalDesktopDirW);
+
+		// Local Settings
+		ms->LocalAppDataDir = CopyStr(ms->PersonalAppDataDir);
+		ms->LocalAppDataDirW = CopyUniStr(ms->PersonalAppDataDirW);
+	}
+}
+
+// 現在のユーザーが Administrators かどうかチェックする
+bool MsCheckIsAdmin()
+{
+	UCHAR test_bit[32];
+	UCHAR tmp[32];
+	char *name = "Vpn_Check_Admin_Key";
+	DWORD type;
+	DWORD size;
+	Rand(test_bit, sizeof(test_bit));
+
+	if (RegSetValueEx(HKEY_LOCAL_MACHINE, name, 0, REG_BINARY, test_bit, sizeof(test_bit)) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	size = sizeof(tmp);
+	if (RegQueryValueEx(HKEY_LOCAL_MACHINE, name, 0, &type, tmp, &size) != ERROR_SUCCESS)
+	{
+		return false;
+	}
+
+	RegDeleteValue(HKEY_LOCAL_MACHINE, name);
+
+	if (Cmp(test_bit, tmp, 32) != 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ライブラリの初期化
+void MsInit()
+{
+	char *str_ansi;
+	wchar_t *str_unicode;
+	OSVERSIONINFO os;
+	char tmp[MAX_SIZE];
+	UINT size;
+	if (ms != NULL)
+	{
+		// すでに初期化されている
+		return;
+	}
+
+	ms = ZeroMalloc(sizeof(MS));
+
+	// インスタンスハンドルの取得
+	ms->hInst = GetModuleHandleA(NULL);
+
+	// KERNEL32.DLL の取得
+	ms->hKernel32 = LoadLibrary("kernel32.dll");
+
+	// OS からコマンドライン文字列を取得する
+	str_ansi = CopyStr(GetCommandLineA());
+	Trim(str_ansi);
+	str_unicode = UniCopyStr(GetCommandLineW());
+	UniTrim(str_unicode);
+
+	SetCommandLineStr(MsCutExeNameFromCommandLine(str_ansi));
+	SetCommandLineUniStr(MsCutExeNameFromUniCommandLine(str_unicode));
+
+	Free(str_unicode);
+	Free(str_ansi);
+
+	// OS のバージョンを取得する
+	Zero(&os, sizeof(os));
+	os.dwOSVersionInfoSize = sizeof(os);
+	GetVersionEx(&os);
+
+	if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
+	{
+		// NT 系
+		ms->IsNt = true;
+
+		ms->nt = MsLoadNtApiFunctions();
+
+		if (ms->nt == NULL)
+		{
+			ms->IsNt = false;
+			ms->IsAdmin = true;
+		}
+		else
+		{
+			// Administrators 判定
+			ms->IsAdmin = MsCheckIsAdmin();
+		}
+	}
+	else
+	{
+		// 9x 系: 常に Administrators を偽装
+		ms->IsAdmin = true;
+	}
+
+	// 現在のプロセスに関する情報を取得する
+	ms->hCurrentProcess = GetCurrentProcess();
+	ms->CurrentProcessId = GetCurrentProcessId();
+
+	// EXE ファイル名を取得
+	GetModuleFileName(NULL, tmp, sizeof(tmp));
+	ms->ExeFileName = CopyStr(tmp);
+	Win32GetDirFromPath(tmp, sizeof(tmp), tmp);
+	ms->ExeFileDir = CopyStr(tmp);
+
+	// EXE ファイル名 (Unicode) を取得
+	if (IsNt())
+	{
+		wchar_t tmp_w[MAX_PATH];
+
+		GetModuleFileNameW(NULL, tmp_w, sizeof(tmp_w));
+		ms->ExeFileNameW = CopyUniStr(tmp_w);
+
+		Win32GetDirFromPathW(tmp_w, sizeof(tmp_w), tmp_w);
+		ms->ExeFileDirW = CopyUniStr(tmp_w);
+	}
+	else
+	{
+		ms->ExeFileNameW = CopyStrToUni(ms->ExeFileName);
+		ms->ExeFileDirW = CopyStrToUni(ms->ExeFileDir);
+	}
+
+	// 特殊なディレクトリを取得
+	MsGetSpecialDirs();
+
+	// 一時ディレクトリの初期化
+	MsInitTempDir();
+
+	// ユーザー名の取得
+	size = sizeof(tmp);
+	GetUserName(tmp, &size);
+	ms->UserName = CopyStr(tmp);
+
+	// ユーザー名の取得 (Unicode)
+	if (IsNt())
+	{
+		wchar_t tmp_w[MAX_PATH];
+
+		size = sizeof(tmp_w);
+
+		GetUserNameW(tmp_w, &size);
+		ms->UserNameW = CopyUniStr(tmp_w);
+	}
+	else
+	{
+		ms->UserNameW = CopyStrToUni(ms->UserName);
+	}
+
+	// フルユーザー名の取得
+	if (ms->nt != NULL && ms->nt->GetUserNameExA != NULL)
+	{
+		wchar_t tmp_w[MAX_PATH];
+
+		size = sizeof(tmp);
+		if (ms->nt->GetUserNameExA(NameSamCompatible, tmp, &size))
+		{
+			ms->UserNameEx = CopyStr(tmp);
+		}
+
+		size = sizeof(tmp_w);
+		if (ms->nt->GetUserNameExW(NameSamCompatible, tmp_w, &size))
+		{
+			ms->UserNameExW = CopyUniStr(tmp_w);
+		}
+	}
+
+	if (ms->UserNameEx == NULL)
+	{
+		ms->UserNameEx = CopyStr(ms->UserName);
+	}
+	if (ms->UserNameExW == NULL)
+	{
+		ms->UserNameExW = CopyUniStr(ms->UserNameW);
+	}
+
+	ms_critical_section = ZeroMalloc(sizeof(CRITICAL_SECTION));
+	InitializeCriticalSection(ms_critical_section);
+
+	// アダプタリストの初期化
+	MsInitAdapterListModule();
+
+	// minidump ベースファイル名の初期化
+	if (true)
+	{
+		wchar_t tmp[MAX_PATH];
+		if (MsIsAdmin())
+		{
+			CombinePathW(tmp, sizeof(tmp), ms->ExeFileDirW, L"vpn_debug\\dump");
+		}
+		else
+		{
+			CombinePathW(tmp, sizeof(tmp), ms->TempDirW, L"vpn_debug\\dump");
+		}
+		ms->MinidumpBaseFileNameW = CopyUniStr(tmp);
+	}
+
+	MsSetEnableMinidump(true);
+
+	if (MsIsNt())
+	{
+		if (ms->nt->MiniDumpWriteDump != NULL)
+		{
+			SetUnhandledExceptionFilter(MsExceptionHandler);
+		}
+	}
+}
+
+// minidump を作成するかどうか選択する
+void MsSetEnableMinidump(bool enabled)
+{
+	ms->MiniDumpEnabled = enabled;
+}
+
+// minidump を出力する
+void MsWriteMinidump(wchar_t *filename, void *ex)
+{
+	wchar_t tmp[MAX_PATH];
+	wchar_t dir[MAX_PATH];
+	HANDLE h;
+	MINIDUMP_EXCEPTION_INFORMATION info;
+	struct _EXCEPTION_POINTERS *exp = (struct _EXCEPTION_POINTERS *)ex;
+
+	if (filename != NULL)
+	{
+		UniStrCpy(tmp, sizeof(tmp), filename);
+	}
+	else
+	{
+		SYSTEMTIME tm;
+
+		Zero(&tm, sizeof(tm));
+		GetLocalTime(&tm);
+
+		UniFormat(tmp, sizeof(tmp), L"%s_%04u%02u%02u_%02u%02u%02u.dmp",
+			ms->MinidumpBaseFileNameW,
+			tm.wYear, tm.wMonth, tm.wDay, tm.wHour, tm.wMinute, tm.wSecond);
+	}
+
+	GetDirNameFromFilePathW(dir, sizeof(dir), tmp);
+
+	CreateDirectoryW(dir, NULL);
+
+	Zero(&info, sizeof(info));
+
+	if (exp != NULL)
+	{
+		info.ThreadId = GetCurrentThreadId();
+		info.ExceptionPointers = exp;
+		info.ClientPointers = true;
+	}
+
+	h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE,
+		FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
+		NULL);
+	if (h != INVALID_HANDLE_VALUE)
+	{
+		ms->nt->MiniDumpWriteDump(ms->hCurrentProcess, ms->CurrentProcessId,
+			h,
+			MiniDumpNormal | MiniDumpWithFullMemory | MiniDumpWithDataSegs |
+			MiniDumpWithHandleData
+			,
+			info.ThreadId == 0 ? NULL : &info, NULL, NULL);
+
+		FlushFileBuffers(h);
+		CloseHandle(h);
+	}
+}
+
+// 例外ハンドラ
+LONG CALLBACK MsExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo)
+{
+	if (ms->MiniDumpEnabled)
+	{
+		MsWriteMinidump(NULL, ExceptionInfo);
+	}
+
+	return EXCEPTION_CONTINUE_SEARCH;
+}
+
+// ライブラリの解放
+void MsFree()
+{
+	if (ms == NULL)
+	{
+		// 初期化されていない
+		return;
+	}
+
+	// アダプタリストの解放
+	MsFreeAdapterListModule();
+
+	// 一時ディレクトリの解放
+	MsFreeTempDir();
+
+	if (ms->IsNt)
+	{
+		// NT 系 API の解放
+		MsFreeNtApiFunctions(ms->nt);
+	}
+
+	// メモリ解放
+	// ANSI
+	Free(ms->WindowsDir);
+	Free(ms->System32Dir);
+	Free(ms->TempDir);
+	Free(ms->WinTempDir);
+	Free(ms->WindowsDrive);
+	Free(ms->ProgramFilesDir);
+	Free(ms->CommonStartMenuDir);
+	Free(ms->CommonProgramsDir);
+	Free(ms->CommonStartupDir);
+	Free(ms->CommonAppDataDir);
+	Free(ms->CommonDesktopDir);
+	Free(ms->PersonalStartMenuDir);
+	Free(ms->PersonalProgramsDir);
+	Free(ms->PersonalStartupDir);
+	Free(ms->PersonalAppDataDir);
+	Free(ms->PersonalDesktopDir);
+	Free(ms->MyDocumentsDir);
+	Free(ms->ExeFileDir);
+	Free(ms->ExeFileName);
+	Free(ms->UserName);
+	Free(ms->UserNameEx);
+	Free(ms->LocalAppDataDir);
+	// Unicode
+	Free(ms->WindowsDirW);
+	Free(ms->System32DirW);
+	Free(ms->TempDirW);
+	Free(ms->WinTempDirW);
+	Free(ms->WindowsDriveW);
+	Free(ms->ProgramFilesDirW);
+	Free(ms->CommonStartMenuDirW);
+	Free(ms->CommonProgramsDirW);
+	Free(ms->CommonStartupDirW);
+	Free(ms->CommonAppDataDirW);
+	Free(ms->CommonDesktopDirW);
+	Free(ms->PersonalStartMenuDirW);
+	Free(ms->PersonalProgramsDirW);
+	Free(ms->PersonalStartupDirW);
+	Free(ms->PersonalAppDataDirW);
+	Free(ms->PersonalDesktopDirW);
+	Free(ms->MyDocumentsDirW);
+	Free(ms->ExeFileDirW);
+	Free(ms->ExeFileNameW);
+	Free(ms->UserNameW);
+	Free(ms->UserNameExW);
+	Free(ms->LocalAppDataDirW);
+	Free(ms->MinidumpBaseFileNameW);
+	Free(ms);
+	ms = NULL;
+
+	Free(ms_critical_section);
+	ms_critical_section = NULL;
+}
+
+// ディレクトリ取得関係
+char *MsGetCommonAppDataDir()
+{
+	return ms->CommonAppDataDir;
+}
+char *MsGetLocalAppDataDir()
+{
+	return ms->LocalAppDataDir;
+}
+char *MsGetWindowsDir()
+{
+	return ms->WindowsDir;
+}
+wchar_t *MsGetWindowsDirW()
+{
+	return ms->WindowsDirW;
+}
+char *MsGetSystem32Dir()
+{
+	return ms->System32Dir;
+}
+char *MsGetTempDir()
+{
+	return ms->TempDir;
+}
+char *MsGetWindowsDrive()
+{
+	return ms->WindowsDrive;
+}
+char *MsGetProgramFilesDir()
+{
+	return ms->ProgramFilesDir;
+}
+char *MsGetCommonStartMenuDir()
+{
+	return ms->CommonStartMenuDir;
+}
+char *MsGetCommonProgramsDir()
+{
+	return ms->CommonProgramsDir;
+}
+char *MsGetCommonStartupDir()
+{
+	return ms->CommonStartupDir;
+}
+char *MsGetCommonDesktopDir()
+{
+	return ms->CommonDesktopDir;
+}
+char *MsGetPersonalStartMenuDir()
+{
+	if (ms->PersonalStartMenuDir == NULL)
+	{
+		ms->PersonalStartMenuDir = MsGetSpecialDir(CSIDL_STARTMENU);
+	}
+	return ms->PersonalStartMenuDir;
+}
+char *MsGetPersonalProgramsDir()
+{
+	if (ms->PersonalProgramsDir == NULL)
+	{
+		ms->PersonalProgramsDir = MsGetSpecialDir(CSIDL_PROGRAMS);
+	}
+	return ms->PersonalProgramsDir;
+}
+char *MsGetPersonalStartupDir()
+{
+	if (ms->PersonalStartupDir == NULL)
+	{
+		ms->PersonalStartupDir = MsGetSpecialDir(CSIDL_STARTUP);
+	}
+	return ms->PersonalStartupDir;
+}
+char *MsGetPersonalAppDataDir()
+{
+	if (ms->PersonalAppDataDir == NULL)
+	{
+		ms->PersonalAppDataDir = MsGetSpecialDir(CSIDL_APPDATA);
+	}
+	return ms->PersonalAppDataDir;
+}
+char *MsGetPersonalDesktopDir()
+{
+	if (ms->PersonalDesktopDir == NULL)
+	{
+		ms->PersonalDesktopDir = MsGetSpecialDir(CSIDL_DESKTOP);
+	}
+	return ms->PersonalDesktopDir;
+}
+char *MsGetMyDocumentsDir()
+{
+	if (ms->MyDocumentsDir == NULL)
+	{
+		ms->MyDocumentsDir = MsGetSpecialDir(CSIDL_PERSONAL);
+	}
+	return ms->MyDocumentsDir;
+}
+char *MsGetMyTempDir()
+{
+	return ms->MyTempDir;
+}
+char *MsGetUserName()
+{
+	return ms->UserName;
+}
+char *MsGetUserNameEx()
+{
+	return ms->UserNameEx;
+}
+char *MsGetWinTempDir()
+{
+	return ms->WinTempDir;
+}
+
+wchar_t *MsGetExeFileNameW()
+{
+	return ms == NULL ? L"Unknown" : ms->ExeFileNameW;
+}
+wchar_t *MsGetExeFileDirW()
+{
+	return ms->ExeFileDirW;
+}
+wchar_t *MsGetWindowDirW()
+{
+	return ms->WindowsDirW;
+}
+wchar_t *MsGetSystem32DirW()
+{
+	return ms->System32DirW;
+}
+wchar_t *MsGetTempDirW()
+{
+	return ms->TempDirW;
+}
+wchar_t *MsGetWindowsDriveW()
+{
+	return ms->WindowsDriveW;
+}
+wchar_t *MsGetProgramFilesDirW()
+{
+	return ms->ProgramFilesDirW;
+}
+wchar_t *MsGetCommonStartMenuDirW()
+{
+	return ms->CommonStartMenuDirW;
+}
+wchar_t *MsGetCommonProgramsDirW()
+{
+	return ms->CommonProgramsDirW;
+}
+wchar_t *MsGetCommonStartupDirW()
+{
+	return ms->CommonStartupDirW;
+}
+wchar_t *MsGetCommonAppDataDirW()
+{
+	return ms->CommonAppDataDirW;
+}
+wchar_t *MsGetCommonDesktopDirW()
+{
+	return ms->CommonDesktopDirW;
+}
+wchar_t *MsGetPersonalStartMenuDirW()
+{
+	if (ms->PersonalStartMenuDirW == NULL)
+	{
+		ms->PersonalStartMenuDirW = MsGetSpecialDirW(CSIDL_STARTMENU);
+	}
+
+	return ms->PersonalStartMenuDirW;
+}
+wchar_t *MsGetPersonalProgramsDirW()
+{
+	if (ms->PersonalProgramsDirW == NULL)
+	{
+		ms->PersonalProgramsDirW = MsGetSpecialDirW(CSIDL_PROGRAMS);
+	}
+
+	return ms->PersonalProgramsDirW;
+}
+wchar_t *MsGetPersonalStartupDirW()
+{
+	if (ms->PersonalStartupDirW == NULL)
+	{
+		ms->PersonalStartupDirW = MsGetSpecialDirW(CSIDL_STARTUP);
+	}
+
+	return ms->PersonalStartupDirW;
+}
+wchar_t *MsGetPersonalAppDataDirW()
+{
+	if (ms->PersonalAppDataDirW == NULL)
+	{
+		ms->PersonalAppDataDirW = MsGetSpecialDirW(CSIDL_APPDATA);
+	}
+
+	return ms->PersonalAppDataDirW;
+}
+wchar_t *MsGetPersonalDesktopDirW()
+{
+	if (ms->PersonalDesktopDirW == NULL)
+	{
+		ms->PersonalDesktopDirW = MsGetSpecialDirW(CSIDL_DESKTOP);
+	}
+
+	return ms->PersonalDesktopDirW;
+}
+wchar_t *MsGetMyDocumentsDirW()
+{
+	if (ms->MyDocumentsDirW == NULL)
+	{
+		ms->MyDocumentsDirW = MsGetSpecialDirW(CSIDL_PERSONAL);
+	}
+
+	return ms->MyDocumentsDirW;
+}
+wchar_t *MsGetLocalAppDataDirW()
+{
+	return ms->LocalAppDataDirW;
+}
+wchar_t *MsGetMyTempDirW()
+{
+	return ms->MyTempDirW;
+}
+wchar_t *MsGetUserNameW()
+{
+	return ms->UserNameW;
+}
+wchar_t *MsGetUserNameExW()
+{
+	return ms->UserNameExW;
+}
+wchar_t *MsGetWinTempDirW()
+{
+	return ms->WinTempDirW;
+}
+
+
+#endif	// WIN32
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Microsoft.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Microsoft.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Microsoft.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,952 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Microsoft.h
+// Microsoft.c のヘッダ
+
+#ifdef	OS_WIN32
+
+// Windows 用の型が windows.h をインクルードしていなくても使えるようにする
+#ifndef	_WINDEF_
+
+typedef void *HWND;
+
+#endif	// _WINDEF_
+
+#ifndef	MICROSOFT_H
+#define	MICROSOFT_H
+
+
+// イベントログ定数
+#define	MS_EVENTLOG_TYPE_INFORMATION		0
+#define	MS_EVENTLOG_TYPE_WARNING			1
+#define	MS_EVENTLOG_TYPE_ERROR				2
+
+#define	MS_RC_EVENTLOG_TYPE_INFORMATION		0x40000001L
+#define	MS_RC_EVENTLOG_TYPE_WARNING			0x80000002L
+#define	MS_RC_EVENTLOG_TYPE_ERROR			0xC0000003L
+
+
+// TCP/IP レジストリ値
+#define	TCP_MAX_NUM_CONNECTIONS				16777214
+
+#define	DEFAULT_TCP_MAX_WINDOW_SIZE_RECV	5955584
+#define	DEFAULT_TCP_MAX_WINDOW_SIZE_SEND	131072
+#define	DEFAULT_TCP_MAX_NUM_CONNECTIONS		16777214
+
+// 定数
+#define	SVC_ARG_INSTALL				"/install"
+#define	SVC_ARG_UNINSTALL			"/uninstall"
+#define	SVC_ARG_START				"/start"
+#define	SVC_ARG_STOP				"/stop"
+#define	SVC_ARG_TEST				"/test"
+#define	SVC_ARG_USERMODE			"/usermode"
+#define	SVC_ARG_USERMODE_SHOWTRAY	"/usermode_showtray"
+#define	SVC_ARG_USERMODE_HIDETRAY	"/usermode_hidetray"
+#define	SVC_ARG_SERVICE				"/service"
+#define	SVC_ARG_SETUP_INSTALL		"/setup_install"
+#define	SVC_ARG_SETUP_UNINSTALL		"/setup_uninstall"
+#define	SVC_ARG_WIN9X_SERVICE		"/win9x_service"
+#define	SVC_ARG_WIN9X_INSTALL		"/win9x_install"
+#define	SVC_ARG_WIN9X_UNINSTALL		"/win9x_uninstall"
+#define	SVC_ARG_TCP					"/tcp"
+#define	SVC_ARG_TCP_SETUP			"/tcpsetup"
+#define	SVC_ARG_TRAFFIC				"/traffic"
+#define	SVC_ARG_UIHELP				"/uihelp"
+#define	SVC_ARG_UIHELP_W			L"/uihelp"
+#define SVC_ARG_SILENT				"/silent"
+
+// サービスがフリーズした場合の自殺までの時間
+#define	SVC_SELFKILL_TIMEOUT		(5 * 60 * 1000)
+
+// Win32 版仮想 LAN カードのデバイスドライバの名称 (先頭部分)
+#define	VLAN_ADAPTER_NAME			"UT-VPN Client Adapter"
+
+// Win32 版仮想 LAN カードのデバイスドライバの名称 (フルネーム)
+#define	VLAN_ADAPTER_NAME_TAG		"UT-VPN Client Adapter - %s"
+
+// Win32 版仮想 LAN カードの [ネットワーク接続] における表示名 (フルネーム)
+#define	VLAN_CONNECTION_NAME		"%s - UT-VPN Client"
+
+
+// サービス時のコマンドライン書式
+#define	SVC_RUN_COMMANDLINE			L"\"%s\" /service"
+
+// モード値
+#define	SVC_MODE_NONE				0
+#define	SVC_MODE_INSTALL			1
+#define	SVC_MODE_UNINSTALL			2
+#define	SVC_MODE_START				3
+#define	SVC_MODE_STOP				4
+#define	SVC_MODE_TEST				5
+#define	SVC_MODE_USERMODE			6
+#define	SVC_MODE_SERVICE			7
+#define	SVC_MODE_SETUP_INSTALL		8
+#define	SVC_MODE_SETUP_UNINSTALL	9
+#define	SVC_MODE_WIN9X_SERVICE		10
+#define	SVC_MODE_WIN9X_INSTALL		11
+#define	SVC_MODE_WIN9X_UNINSTALL	12
+#define	SVC_MODE_TCP				13
+#define	SVC_MODE_TCPSETUP			14
+#define	SVC_MODE_TRAFFIC			15
+#define	SVC_MODE_UIHELP				16
+
+
+#define	WIN9X_SVC_REGKEY_1			"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices"
+#define	WIN9X_SVC_REGKEY_2			"Software\\Microsoft\\Windows\\CurrentVersion\\Run"
+
+#define	VISTA_MMCSS_KEYNAME			"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Multimedia\\SystemProfile\\Tasks"
+#define	VISTA_MMCSS_FILENAME		"mmcss_backup.dat"
+
+#define	SVC_NAME					"SVC_%s_NAME"
+#define	SVC_TITLE					"SVC_%s_TITLE"
+#define	SVC_DESCRIPT				"SVC_%s_DESCRIPT"
+
+#define	SVC_USERMODE_SETTING_KEY	"Software\\SoftEther Corporation\\UT-VPN\\UserMode Settings"
+#define	SVC_HIDETRAY_REG_VALUE		"HideTray_%S"
+
+#define	SVC_CALLING_SM_PROCESS_ID_KEY	"Software\\SoftEther Corporation\\UT-VPN\\Service Control\\%s"
+#define SVC_CALLING_SM_PROCESS_ID_VALUE	"ProcessId"
+
+#define	MMCSS_PROFILE_KEYNAME		"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Multimedia\\SystemProfile"
+
+// その他の定数
+#define	MS_REG_TCP_SETTING_KEY		"Software\\SoftEther Corporation\\Network Settings"
+
+
+
+// ドライバ関係の定数
+#define	DRIVER_INF_FILE_NAME		L"|vpn_driver.inf"
+#define	DRIVER_INF_FILE_NAME_X64	L"|vpn_driver_x64.inf"
+#define	DRIVER_INF_FILE_NAME_IA64	L"|vpn_driver_ia64.inf"
+#define	DRIVER_INF_FILE_NAME_9X		L"|vpn_driver_9x.inf"
+#define	DRIVER_SYS_FILE_NAME		L"|vpn_driver.sys"
+#define	DRIVER_SYS_FILE_NAME_X64	L"|vpn_driver_x64.sys"
+#define	DRIVER_SYS_FILE_NAME_IA64	L"|vpn_driver_ia64.sys"
+#define	DRIVER_SYS_FILE_NAME_9X		L"|vpn_driver_9x.sys"
+#define	DRIVER_INSTALL_INF_NAME_TAG	"Sen_%s.inf"
+#define	DRIVER_INSTALL_SYS_NAME_TAG	"Sen_%s.sys"
+#define	DRIVER_INSTALL_SYS_NAME_TAG_NEW	"Sen_%04u.sys"
+#define	DRIVER_INSTALL_SYS_NAME_TAG_MAXID	128
+
+// Vista 用ドライバインストーラ関係
+#define	VISTA_DRIVER_INSTALLER_SRC	L"|driver_installer.exe"
+#define	VISTA_DRIVER_INSTALLER_SRC_X64	L"|driver_installer_x64.exe"
+#define	VISTA_DRIVER_INSTALLER_SRC_IA64	L"|driver_installer_ia64.exe"
+#define	VISTA_DRIVER_INSTALLER_DST	L"%s\\driver_installer.exe"
+
+#define	DRIVER_DEVICE_ID_TAG		"SenAdapter_%s"
+
+
+#if		(defined(MICROSOFT_C) || defined(NETWORK_C)) && (defined(OS_WIN32))
+
+typedef enum __TCP_TABLE_CLASS {
+	_TCP_TABLE_BASIC_LISTENER,
+	_TCP_TABLE_BASIC_CONNECTIONS,
+	_TCP_TABLE_BASIC_ALL,
+	_TCP_TABLE_OWNER_PID_LISTENER,
+	_TCP_TABLE_OWNER_PID_CONNECTIONS,
+	_TCP_TABLE_OWNER_PID_ALL,
+	_TCP_TABLE_OWNER_MODULE_LISTENER,
+	_TCP_TABLE_OWNER_MODULE_CONNECTIONS,
+	_TCP_TABLE_OWNER_MODULE_ALL
+} _TCP_TABLE_CLASS, *_PTCP_TABLE_CLASS;
+
+// Win32 ネットワーク関係の API 関数へのポインタ
+typedef struct NETWORK_WIN32_FUNCTIONS
+{
+	HINSTANCE hIpHlpApi32;
+	DWORD (WINAPI *DeleteIpForwardEntry)(PMIB_IPFORWARDROW);
+	DWORD (WINAPI *CreateIpForwardEntry)(PMIB_IPFORWARDROW);
+	DWORD (WINAPI *GetIpForwardTable)(PMIB_IPFORWARDTABLE, PULONG, BOOL);
+	DWORD (WINAPI *GetNetworkParams)(PFIXED_INFO, PULONG);
+	DWORD (WINAPI *GetIfTable)(PMIB_IFTABLE, PULONG, BOOL);
+	DWORD (WINAPI *IpRenewAddress)(PIP_ADAPTER_INDEX_MAP);
+	DWORD (WINAPI *IpReleaseAddress)(PIP_ADAPTER_INDEX_MAP);
+	DWORD (WINAPI *GetInterfaceInfo)(PIP_INTERFACE_INFO, PULONG);
+	DWORD (WINAPI *GetAdaptersInfo)(PIP_ADAPTER_INFO, PULONG);
+	DWORD (WINAPI *GetExtendedTcpTable)(PVOID, PDWORD, BOOL, ULONG, _TCP_TABLE_CLASS, ULONG);
+	DWORD (WINAPI *AllocateAndGetTcpExTableFromStack)(PVOID *, BOOL, HANDLE, DWORD, DWORD);
+	DWORD (WINAPI *GetTcpTable)(PMIB_TCPTABLE, PDWORD, BOOL);
+	DWORD (WINAPI *NotifyRouteChange)(PHANDLE, LPOVERLAPPED);
+	BOOL (WINAPI *CancelIPChangeNotify)(LPOVERLAPPED);
+	DWORD (WINAPI *NhpAllocateAndGetInterfaceInfoFromStack)(IP_INTERFACE_NAME_INFO **,
+		PDWORD, BOOL, HANDLE, DWORD);
+} NETWORK_WIN32_FUNCTIONS;
+#endif
+
+
+#ifdef	MICROSOFT_C
+// 内部用構造体
+typedef struct MS
+{
+	HINSTANCE hInst;
+	HINSTANCE hKernel32;
+	bool IsNt;
+	bool IsAdmin;
+	struct NT_API *nt;
+	HANDLE hCurrentProcess;
+	UINT CurrentProcessId;
+	bool MiniDumpEnabled;
+	char *ExeFileName;
+	char *ExeFileDir;
+	char *WindowsDir;
+	char *System32Dir;
+	char *TempDir;
+	char *WinTempDir;
+	char *WindowsDrive;
+	char *ProgramFilesDir;
+	char *CommonStartMenuDir;
+	char *CommonProgramsDir;
+	char *CommonStartupDir;
+	char *CommonAppDataDir;
+	char *CommonDesktopDir;
+	char *PersonalStartMenuDir;
+	char *PersonalProgramsDir;
+	char *PersonalStartupDir;
+	char *PersonalAppDataDir;
+	char *PersonalDesktopDir;
+	char *MyDocumentsDir;
+	char *LocalAppDataDir;
+	char *MyTempDir;
+	char *UserName;
+	char *UserNameEx;
+	wchar_t *ExeFileNameW;
+	wchar_t *ExeFileDirW;
+	wchar_t *WindowsDirW;
+	wchar_t *System32DirW;
+	wchar_t *TempDirW;
+	wchar_t *WinTempDirW;
+	wchar_t *WindowsDriveW;
+	wchar_t *ProgramFilesDirW;
+	wchar_t *CommonStartMenuDirW;
+	wchar_t *CommonProgramsDirW;
+	wchar_t *CommonStartupDirW;
+	wchar_t *CommonAppDataDirW;
+	wchar_t *CommonDesktopDirW;
+	wchar_t *PersonalStartMenuDirW;
+	wchar_t *PersonalProgramsDirW;
+	wchar_t *PersonalStartupDirW;
+	wchar_t *PersonalAppDataDirW;
+	wchar_t *PersonalDesktopDirW;
+	wchar_t *MyDocumentsDirW;
+	wchar_t *LocalAppDataDirW;
+	wchar_t *MyTempDirW;
+	wchar_t *UserNameW;
+	wchar_t *UserNameExW;
+	wchar_t *MinidumpBaseFileNameW;
+	IO *LockFile;
+} MS;
+
+// Windows NT 用 API
+typedef struct NT_API
+{
+	HINSTANCE hAdvapi32;
+	HINSTANCE hShell32;
+	HINSTANCE hNewDev;
+	HINSTANCE hSetupApi;
+	HINSTANCE hWtsApi32;
+	HINSTANCE hPsApi;
+	HINSTANCE hKernel32;
+	HINSTANCE hSecur32;
+	HINSTANCE hUser32;
+	HINSTANCE hDbgHelp;
+	BOOL (WINAPI *OpenProcessToken)(HANDLE, DWORD, PHANDLE);
+	BOOL (WINAPI *LookupPrivilegeValue)(char *, char *, PLUID);
+	BOOL (WINAPI *AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD);
+	BOOL (WINAPI *InitiateSystemShutdown)(LPTSTR, LPTSTR, DWORD, BOOL, BOOL);
+	BOOL (WINAPI *LogonUserW)(wchar_t *, wchar_t *, wchar_t *, DWORD, DWORD, HANDLE *);
+	BOOL (WINAPI *LogonUserA)(char *, char *, char *, DWORD, DWORD, HANDLE *);
+	BOOL (WINAPI *UpdateDriverForPlugAndPlayDevicesW)(HWND hWnd, wchar_t *hardware_id, wchar_t *inf_path, UINT flag, BOOL *need_reboot);
+	UINT (WINAPI *CM_Get_DevNode_Status_Ex)(UINT *, UINT *, DWORD, UINT, HANDLE);
+	UINT (WINAPI *CM_Get_Device_ID_ExA)(DWORD, char *, UINT, UINT, HANDLE);
+	UINT (WINAPI *WTSQuerySessionInformation)(HANDLE, DWORD, WTS_INFO_CLASS, wchar_t *, DWORD *);
+	void (WINAPI *WTSFreeMemory)(void *);
+	BOOL (WINAPI *WTSDisconnectSession)(HANDLE, DWORD, BOOL);
+	BOOL (WINAPI *WTSEnumerateSessions)(HANDLE, DWORD, DWORD, PWTS_SESSION_INFO *, DWORD *);
+	SC_HANDLE (WINAPI *OpenSCManager)(LPCTSTR, LPCTSTR, DWORD);
+	SC_HANDLE (WINAPI *CreateServiceA)(SC_HANDLE, LPCTSTR, LPCTSTR, DWORD, DWORD, DWORD, DWORD, LPCTSTR, LPCTSTR, LPDWORD, LPCTSTR, LPCTSTR, LPCTSTR);
+	SC_HANDLE (WINAPI *CreateServiceW)(SC_HANDLE, LPCWSTR, LPCWSTR, DWORD, DWORD, DWORD, DWORD, LPCWSTR, LPCWSTR, LPDWORD, LPCWSTR, LPCWSTR, LPCWSTR);
+	BOOL (WINAPI *ChangeServiceConfig2)(SC_HANDLE, DWORD, LPVOID);
+	BOOL (WINAPI *CloseServiceHandle)(SC_HANDLE);
+	SC_HANDLE (WINAPI *OpenService)(SC_HANDLE, LPCTSTR, DWORD);
+	BOOL (WINAPI *QueryServiceStatus)(SC_HANDLE, LPSERVICE_STATUS);
+	BOOL (WINAPI *StartService)(SC_HANDLE, DWORD, LPCTSTR);
+	BOOL (WINAPI *ControlService)(SC_HANDLE, DWORD, LPSERVICE_STATUS);
+	BOOL (WINAPI *SetServiceStatus)(SERVICE_STATUS_HANDLE, LPSERVICE_STATUS);
+	SERVICE_STATUS_HANDLE (WINAPI *RegisterServiceCtrlHandler)(LPCTSTR, LPHANDLER_FUNCTION);
+	BOOL (WINAPI *StartServiceCtrlDispatcher)(CONST LPSERVICE_TABLE_ENTRY);
+	BOOL (WINAPI *DeleteService)(SC_HANDLE);
+	BOOL (WINAPI *EnumProcesses)(DWORD *, DWORD, DWORD *);
+	BOOL (WINAPI *EnumProcessModules)(HANDLE, HMODULE *, DWORD, DWORD *);
+	DWORD (WINAPI *GetModuleFileNameExA)(HANDLE, HMODULE, LPSTR, DWORD);
+	DWORD (WINAPI *GetModuleFileNameExW)(HANDLE, HMODULE, LPWSTR, DWORD);
+	LONG (WINAPI *RegDeleteKeyExA)(HKEY, LPCTSTR, REGSAM, DWORD);
+	BOOL (WINAPI *IsWow64Process)(HANDLE, BOOL *);
+	void (WINAPI *GetNativeSystemInfo)(SYSTEM_INFO *);
+	BOOL (WINAPI *DuplicateTokenEx)(HANDLE, DWORD, SECURITY_ATTRIBUTES *, SECURITY_IMPERSONATION_LEVEL, TOKEN_TYPE, HANDLE *);
+	BOOL (WINAPI *ConvertStringSidToSidA)(LPCSTR, PSID *);
+	BOOL (WINAPI *SetTokenInformation)(HANDLE, TOKEN_INFORMATION_CLASS, void *, DWORD);
+	BOOL (WINAPI *GetTokenInformation)(HANDLE, TOKEN_INFORMATION_CLASS, void *, DWORD, PDWORD);
+	BOOL (WINAPI *CreateProcessAsUserA)(HANDLE, LPCSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, void *, LPCSTR, LPSTARTUPINFOA, LPPROCESS_INFORMATION);
+	BOOL (WINAPI *CreateProcessAsUserW)(HANDLE, LPCWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, void *, LPCWSTR, LPSTARTUPINFOW, LPPROCESS_INFORMATION);
+	BOOL (WINAPI *LookupAccountSidA)(LPCSTR,PSID,LPSTR,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE);
+	BOOL (WINAPI *LookupAccountNameA)(LPCSTR,LPCSTR,PSID,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE);
+	BOOL (WINAPI *GetUserNameExA)(EXTENDED_NAME_FORMAT, LPSTR, PULONG);
+	BOOL (WINAPI *GetUserNameExW)(EXTENDED_NAME_FORMAT, LPWSTR, PULONG);
+	BOOL (WINAPI *SwitchDesktop)(HDESK);
+	HDESK (WINAPI *OpenDesktopA)(LPTSTR, DWORD, BOOL, ACCESS_MASK);
+	BOOL (WINAPI *CloseDesktop)(HDESK);
+	BOOL (WINAPI *SetProcessShutdownParameters)(DWORD, DWORD);
+	HANDLE (WINAPI *RegisterEventSourceW)(LPCWSTR, LPCWSTR);
+	BOOL (WINAPI *ReportEventW)(HANDLE, WORD, WORD, DWORD, PSID, WORD, DWORD, LPCWSTR *, LPVOID);
+	BOOL (WINAPI *DeregisterEventSource)(HANDLE);
+	BOOL (WINAPI *Wow64DisableWow64FsRedirection)(void **);
+	BOOLEAN (WINAPI *Wow64EnableWow64FsRedirection)(BOOLEAN);
+	BOOL (WINAPI *Wow64RevertWow64FsRedirection)(void *);
+	BOOL (WINAPI *GetFileInformationByHandle)(HANDLE, LPBY_HANDLE_FILE_INFORMATION);
+	HANDLE (WINAPI *GetProcessHeap)();
+	BOOL (WINAPI *MiniDumpWriteDump)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE,
+		PMINIDUMP_EXCEPTION_INFORMATION, PMINIDUMP_USER_STREAM_INFORMATION,
+		PMINIDUMP_CALLBACK_INFORMATION);
+} NT_API;
+
+typedef struct MS_EVENTLOG
+{
+	HANDLE hEventLog;
+} MS_EVENTLOG;
+
+extern NETWORK_WIN32_FUNCTIONS *w32net;
+
+#endif	// MICROSOFT_C
+
+// 警告を出さないようにするための構造体
+typedef struct NO_WARNING
+{
+	DWORD ThreadId;
+	THREAD *NoWarningThread;
+	EVENT *HaltEvent;
+	volatile bool Halt;
+	wchar_t *SoundFileName;
+} NO_WARNING;
+
+// ルートキーの ID
+#define	REG_CLASSES_ROOT		0	// HKEY_CLASSES_ROOT
+#define	REG_LOCAL_MACHINE		1	// HKEY_LOCAL_MACHINE
+#define	REG_CURRENT_USER		2	// HKEY_CURRENT_USER
+#define	REG_USERS				3	// HKEY_USERS
+
+// サービス関数
+typedef void (SERVICE_FUNCTION)();
+
+// プロセスリスト項目
+typedef struct MS_PROCESS
+{
+	char ExeFilename[MAX_PATH];		// EXE ファイル名
+	wchar_t ExeFilenameW[MAX_PATH];	// EXE ファイル名 (Unicode)
+	UINT ProcessId;					// プロセス ID
+} MS_PROCESS;
+
+#define	MAX_MS_ADAPTER_IP_ADDRESS	64
+
+// ネットワークアダプタ
+typedef struct MS_ADAPTER
+{
+	char Title[MAX_PATH];			// 表示名
+	UINT Index;						// インデックス
+	UINT Type;						// 種類
+	UINT Status;					// ステータス
+	UINT Mtu;						// MTU
+	UINT Speed;						// 速度
+	UINT AddressSize;				// アドレスサイズ
+	UCHAR Address[8];				// アドレス
+	UINT64 RecvBytes;				// 受信バイト数
+	UINT64 RecvPacketsBroadcast;	// 受信ブロードキャストパケット数
+	UINT64 RecvPacketsUnicast;		// 受信ユニキャストパケット数
+	UINT64 SendBytes;				// 送信バイト数
+	UINT64 SendPacketsBroadcast;	// 送信ブロードキャストパケット数
+	UINT64 SendPacketsUnicast;		// 送信ユニキャストパケット数
+	bool Info;						// 詳しい情報があるかどうか
+	char Guid[MAX_SIZE];			// GUID
+	UINT NumIpAddress;				// IP アドレス個数
+	IP IpAddresses[MAX_MS_ADAPTER_IP_ADDRESS];	// IP アドレス
+	IP SubnetMasks[MAX_MS_ADAPTER_IP_ADDRESS];	// サブネット マスク
+	UINT NumGateway;				// ゲートウェイ個数
+	IP Gateways[MAX_MS_ADAPTER_IP_ADDRESS];	// ゲートウェイ
+	bool UseDhcp;					// DHCP 使用フラグ
+	IP DhcpServer;					// DHCP サーバー
+	UINT64 DhcpLeaseStart;			// DHCP リース開始日時
+	UINT64 DhcpLeaseExpires;		// DHCP リース期限日時
+	bool UseWins;					// WINS 使用フラグ
+	IP PrimaryWinsServer;			// プライマリ WINS サーバー
+	IP SecondaryWinsServer;			// セカンダリ WINS サーバー
+} MS_ADAPTER;
+
+// ネットワークアダプタリスト
+typedef struct MS_ADAPTER_LIST
+{
+	UINT Num;						// 個数
+	MS_ADAPTER **Adapters;			// 内容
+} MS_ADAPTER_LIST;
+
+// TCP 設定
+typedef struct MS_TCP
+{
+	UINT RecvWindowSize;			// 受信ウインドウサイズ
+	UINT SendWindowSize;			// 送信ウインドウサイズ
+} MS_TCP;
+
+// スリープ防止
+typedef struct MS_NOSLEEP
+{
+	THREAD *Thread;					// スレッド
+	EVENT *HaltEvent;				// 停止イベント
+	volatile bool Halt;				// 停止フラグ
+	bool NoScreenSaver;				// スクリーンセーバーも防止
+
+	// 以下 Windows Vista 用
+	wchar_t ScreenSaveActive[MAX_PATH];
+	wchar_t SCRNSAVE_EXE[MAX_PATH];
+} MS_NOSLEEP;
+
+// 子ウインドウ列挙
+typedef struct ENUM_CHILD_WINDOW_PARAM
+{
+	LIST *o;
+	bool no_recursion;
+	bool include_ipcontrol;
+} ENUM_CHILD_WINDOW_PARAM;
+
+// 関数プロトタイプ
+void MsInit();
+void MsFree();
+char *MsCutExeNameFromCommandLine(char *str);
+wchar_t *MsCutExeNameFromUniCommandLine(wchar_t *str);
+
+DWORD MsRegAccessMaskFor64Bit(bool force32bit);
+DWORD MsRegAccessMaskFor64BitEx(bool force32bit, bool force64bit);
+
+bool MsRegIsKey(UINT root, char *name);
+bool MsRegIsKeyEx(UINT root, char *name, bool force32bit);
+bool MsRegIsKeyEx2(UINT root, char *name, bool force32bit, bool force64bit);
+
+bool MsRegIsValue(UINT root, char *keyname, char *valuename);
+bool MsRegIsValueEx(UINT root, char *keyname, char *valuename, bool force32bit);
+bool MsRegIsValueEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit);
+
+bool MsRegGetValueTypeAndSize(UINT root, char *keyname, char *valuename, UINT *type, UINT *size);
+bool MsRegGetValueTypeAndSizeEx(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit);
+bool MsRegGetValueTypeAndSizeEx2(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit);
+bool MsRegGetValueTypeAndSizeW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size);
+bool MsRegGetValueTypeAndSizeExW(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit);
+bool MsRegGetValueTypeAndSizeEx2W(UINT root, char *keyname, char *valuename, UINT *type, UINT *size, bool force32bit, bool force64bit);
+
+bool MsRegReadValue(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size);
+bool MsRegReadValueEx(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit);
+bool MsRegReadValueEx2(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit);
+bool MsRegReadValueW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size);
+bool MsRegReadValueExW(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit);
+bool MsRegReadValueEx2W(UINT root, char *keyname, char *valuename, void **data, UINT *type, UINT *size, bool force32bit, bool force64bit);
+
+char *MsRegReadStr(UINT root, char *keyname, char *valuename);
+char *MsRegReadStrEx(UINT root, char *keyname, char *valuename, bool force32bit);
+char *MsRegReadStrEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit);
+wchar_t *MsRegReadStrW(UINT root, char *keyname, char *valuename);
+wchar_t *MsRegReadStrExW(UINT root, char *keyname, char *valuename, bool force32bit);
+wchar_t *MsRegReadStrEx2W(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit);
+
+UINT MsRegReadInt(UINT root, char *keyname, char *valuename);
+UINT MsRegReadIntEx(UINT root, char *keyname, char *valuename, bool force32bit);
+UINT MsRegReadIntEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit);
+LIST *MsRegReadStrList(UINT root, char *keyname, char *valuename);
+LIST *MsRegReadStrListEx(UINT root, char *keyname, char *valuename, bool force32bit);
+LIST *MsRegReadStrListEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit);
+
+BUF *MsRegReadBin(UINT root, char *keyname, char *valuename);
+BUF *MsRegReadBinEx(UINT root, char *keyname, char *valuename, bool force32bit);
+BUF *MsRegReadBinEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit);
+
+bool MsRegNewKey(UINT root, char *keyname);
+bool MsRegNewKeyEx(UINT root, char *keyname, bool force32bit);
+bool MsRegNewKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit);
+
+bool MsRegWriteValue(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size);
+bool MsRegWriteValueEx(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit);
+bool MsRegWriteValueEx2(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit, bool force64bit);
+bool MsRegWriteValueW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size);
+bool MsRegWriteValueExW(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit);
+bool MsRegWriteValueEx2W(UINT root, char *keyname, char *valuename, UINT type, void *data, UINT size, bool force32bit, bool force64bit);
+
+bool MsRegWriteStr(UINT root, char *keyname, char *valuename, char *str);
+bool MsRegWriteStrEx(UINT root, char *keyname, char *valuename, char *str, bool force32bit);
+bool MsRegWriteStrEx2(UINT root, char *keyname, char *valuename, char *str, bool force32bit, bool force64bit);
+bool MsRegWriteStrExpand(UINT root, char *keyname, char *valuename, char *str);
+bool MsRegWriteStrExpandEx(UINT root, char *keyname, char *valuename, char *str, bool force32bit);
+bool MsRegWriteStrExpandEx2(UINT root, char *keyname, char *valuename, char *str, bool force32bit, bool force64bit);
+bool MsRegWriteStrW(UINT root, char *keyname, char *valuename, wchar_t *str);
+bool MsRegWriteStrExW(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit);
+bool MsRegWriteStrEx2W(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit, bool force64bit);
+bool MsRegWriteStrExpandW(UINT root, char *keyname, char *valuename, wchar_t *str);
+bool MsRegWriteStrExpandExW(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit);
+bool MsRegWriteStrExpandEx2W(UINT root, char *keyname, char *valuename, wchar_t *str, bool force32bit, bool force64bit);
+
+bool MsRegWriteInt(UINT root, char *keyname, char *valuename, UINT value);
+bool MsRegWriteIntEx(UINT root, char *keyname, char *valuename, UINT value, bool force32bit);
+bool MsRegWriteIntEx2(UINT root, char *keyname, char *valuename, UINT value, bool force32bit, bool force64bit);
+bool MsRegWriteBin(UINT root, char *keyname, char *valuename, void *data, UINT size);
+bool MsRegWriteBinEx(UINT root, char *keyname, char *valuename, void *data, UINT size, bool force32bit);
+bool MsRegWriteBinEx2(UINT root, char *keyname, char *valuename, void *data, UINT size, bool force32bit, bool force64bit);
+
+TOKEN_LIST *MsRegEnumKey(UINT root, char *keyname);
+TOKEN_LIST *MsRegEnumKeyEx(UINT root, char *keyname, bool force32bit);
+TOKEN_LIST *MsRegEnumKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit);
+TOKEN_LIST *MsRegEnumValue(UINT root, char *keyname);
+TOKEN_LIST *MsRegEnumValueEx(UINT root, char *keyname, bool force32bit);
+TOKEN_LIST *MsRegEnumValueEx2(UINT root, char *keyname, bool force32bit, bool force64bit);
+
+bool MsRegDeleteKey(UINT root, char *keyname);
+bool MsRegDeleteKeyEx(UINT root, char *keyname, bool force32bit);
+bool MsRegDeleteKeyEx2(UINT root, char *keyname, bool force32bit, bool force64bit);
+bool MsRegDeleteValue(UINT root, char *keyname, char *valuename);
+bool MsRegDeleteValueEx(UINT root, char *keyname, char *valuename, bool force32bit);
+bool MsRegDeleteValueEx2(UINT root, char *keyname, char *valuename, bool force32bit, bool force64bit);
+
+bool MsIsNt();
+bool MsIsAdmin();
+bool MsEnablePrivilege(char *name, bool enable);
+void *MsGetCurrentProcess();
+UINT MsGetCurrentProcessId();
+char *MsGetExeFileName();
+char *MsGetExeDirName();
+wchar_t *MsGetExeDirNameW();
+
+bool MsShutdown(bool reboot, bool force);
+bool MsShutdownEx(bool reboot, bool force, UINT time_limit, char *message);
+bool MsCheckLogon(wchar_t *username, char *password);
+bool MsIsPasswordEmpty(wchar_t *username);
+TOKEN_LIST *MsEnumNetworkAdapters(char *start_with_name, char *start_with_name_2);
+TOKEN_LIST *MsEnumNetworkAdaptersSen();
+bool MsGetSenDeiverFilename(char *name, UINT size, char *instance_name);
+bool MsMakeNewSenDriverFilename(char *name, UINT size);
+void MsGenerateSenDriverFilenameFromInt(char *name, UINT size, UINT n);
+TOKEN_LIST *MsEnumSenDriverFilenames();
+char *MsGetNetworkAdapterGuid(char *tag_name, char *instance_name);
+wchar_t *MsGetNetworkConnectionName(char *guid);
+char *MsGetNetworkConfigRegKeyNameFromGuid(char *guid);
+char *MsGetNetworkConfigRegKeyNameFromInstanceName(char *tag_name, char *instance_name);
+void MsSetNetworkConfig(char *tag_name, char *instance_name, char *friendly_name, bool show_icon);
+void MsInitNetworkConfig(char *tag_name, char *instance_name, char *connection_tag_name);
+
+char *MsGetSpecialDir(int id);
+wchar_t *MsGetSpecialDirW(int id);
+void MsGetSpecialDirs();
+bool MsCheckIsAdmin();
+void MsInitTempDir();
+void MsFreeTempDir();
+void MsGenLockFile(wchar_t *name, UINT size, wchar_t *temp_dir);
+void MsDeleteTempDir();
+void MsDeleteAllFile(char *dir);
+void MsDeleteAllFileW(wchar_t *dir);
+char *MsCreateTempFileName(char *name);
+char *MsCreateTempFileNameByExt(char *ext);
+IO *MsCreateTempFile(char *name);
+IO *MsCreateTempFileByExt(char *ext);
+
+bool MsShowNetworkConfiguration(HWND hWnd);
+
+bool MsInstallVLan(char *tag_name, char *connection_tag_name, char *instance_name);
+bool MsUpgradeVLan(char *tag_name, char *connection_tag_name, char *instance_name);
+bool MsEnableVLan(char *instance_name);
+bool MsDisableVLan(char *instance_name);
+bool MsUninstallVLan(char *instance_name);
+bool MsIsVLanEnabled(char *instance_name);
+void MsRestartVLan(char *instance_name);
+bool MsIsVLanExists(char *tag_name, char *instance_name);
+bool MsStartDriverInstall(char *instance_name, UCHAR *mac_address, char *sen_sys);
+void MsFinishDriverInstall(char *instance_name, char *sen_sys);
+void MsGetDriverPath(char *instance_name, wchar_t *src_inf, wchar_t *src_sys, wchar_t *dest_inf, wchar_t *dest_sys, char *sen_sys);
+void MsGetDriverPathA(char *instance_name, char *src_inf, char *src_sys, char *dest_inf, char *dest_sys, char *sen_sys);
+void MsGenMacAddress(UCHAR *mac);
+char *MsGetMacAddress(char *tag_name, char *instance_name);
+void MsSetMacAddress(char *tag_name, char *instance_name, char *mac_address);
+char *MsGetDriverVersion(char *tag_name, char *instance_name);
+char *MsGetDriverFileName(char *tag_name, char *instance_name);
+void MsTest();
+void MsInitGlobalNetworkConfig();
+void MsSetThreadPriorityHigh();
+void MsSetThreadPriorityLow();
+void MsSetThreadPriorityIdle();
+void MsSetThreadPriorityRealtime();
+void MsRestoreThreadPriority();
+char *MsGetLocalAppDataDir();
+char *MsGetCommonAppDataDir();
+char *MsGetWindowsDir();
+char *MsGetSystem32Dir();
+char *MsGetTempDir();
+char *MsGetWindowsDrive();
+char *MsGetProgramFilesDir();
+char *MsGetCommonStartMenuDir();
+char *MsGetCommonProgramsDir();
+char *MsGetCommonStartupDir();
+char *MsGetCommonAppDataDir();
+char *MsGetCommonDesktopDir();
+char *MsGetPersonalStartMenuDir();
+char *MsGetPersonalProgramsDir();
+char *MsGetPersonalStartupDir();
+char *MsGetPersonalAppDataDir();
+char *MsGetPersonalDesktopDir();
+char *MsGetMyDocumentsDir();
+char *MsGetMyTempDir();
+char *MsGetUserName();
+char *MsGetUserNameEx();
+char *MsGetWinTempDir();
+wchar_t *MsGetWindowsDirW();
+wchar_t *MsGetExeFileNameW();
+wchar_t *MsGetExeFileDirW();
+wchar_t *MsGetWindowDirW();
+wchar_t *MsGetSystem32DirW();
+wchar_t *MsGetTempDirW();
+wchar_t *MsGetWindowsDriveW();
+wchar_t *MsGetProgramFilesDirW();
+wchar_t *MsGetCommonStartMenuDirW();
+wchar_t *MsGetCommonProgramsDirW();
+wchar_t *MsGetCommonStartupDirW();
+wchar_t *MsGetCommonAppDataDirW();
+wchar_t *MsGetCommonDesktopDirW();
+wchar_t *MsGetPersonalStartMenuDirW();
+wchar_t *MsGetPersonalProgramsDirW();
+wchar_t *MsGetPersonalStartupDirW();
+wchar_t *MsGetPersonalAppDataDirW();
+wchar_t *MsGetPersonalDesktopDirW();
+wchar_t *MsGetMyDocumentsDirW();
+wchar_t *MsGetLocalAppDataDirW();
+wchar_t *MsGetMyTempDirW();
+wchar_t *MsGetUserNameW();
+wchar_t *MsGetUserNameExW();
+wchar_t *MsGetWinTempDirW();
+UINT MsGetProcessId();
+void MsTerminateProcess();
+bool MsIsServiceInstalled(char *name);
+bool MsInstallService(char *name, char *title, wchar_t *description, char *path);
+bool MsInstallServiceExW(char *name, wchar_t *title, wchar_t *description, wchar_t *path, UINT *error_code);
+bool MsInstallServiceW(char *name, wchar_t *title, wchar_t *description, wchar_t *path);
+bool MsUpdateServiceConfig(char *name);
+bool MsUninstallService(char *name);
+bool MsStartService(char *name);
+bool MsStartServiceEx(char *name, UINT *error_code);
+bool MsStopService(char *name);
+bool MsIsServiceRunning(char *name);
+bool MsIsTerminalServiceInstalled();
+bool MsIsUserSwitchingInstalled();
+bool MsIsTerminalServiceMultiUserInstalled();
+UINT MsGetCurrentTerminalSessionId();
+bool MsIsTerminalSessionActive(UINT session_id);
+bool MsIsCurrentTerminalSessionActive();
+bool MsIsCurrentDesktopAvailableForVnc();
+wchar_t *MsGetSessionUserName(UINT session_id);
+UINT MsService(char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon);
+void MsTestModeW(wchar_t *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop);
+void MsTestMode(char *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop);
+void MsServiceMode(SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop);
+void MsUserModeW(wchar_t *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon);
+void MsUserMode(char *title, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop, UINT icon);
+bool MsIsUserMode();
+void MsTestOnly();
+void MsStopUserModeFromService();
+char *MsGetPenCoreDllFileName();
+void MsPlaySound(char *name);
+void MsSetThreadSingleCpu();
+void MsWin9xTest();
+bool MsCheckVLanDeviceIdFromRootEnum(char *name);
+bool MsInstallVLan9x(char *instance_name);
+void MsUpdateCompatibleIDs(char *instance_name);
+LIST *MsGetProcessList();
+LIST *MsGetProcessList9x();
+LIST *MsGetProcessListNt();
+void MsFreeProcessList(LIST *o);
+void MsPrintProcessList(LIST *o);
+int MsCompareProcessList(void *p1, void *p2);
+MS_PROCESS *MsSearchProcessById(LIST *o, UINT id);
+void MsGetCurrentProcessExeName(char *name, UINT size);
+void MsGetCurrentProcessExeNameW(wchar_t *name, UINT size);
+bool MsKillProcess(UINT id);
+void MsKillOtherInstance();
+void MsKillOtherInstanceEx(char *exclude_svcname);
+bool MsGetShortPathNameA(char *long_path, char *short_path, UINT short_path_size);
+bool MsGetShortPathNameW(wchar_t *long_path, wchar_t *short_path, UINT short_path_size);
+void MsWriteCallingServiceManagerProcessId(char *svcname, UINT pid);
+UINT MsReadCallingServiceManagerProcessId(char *svcname, bool current_user);
+
+
+MS_ADAPTER_LIST *MsCreateAdapterListInner();
+MS_ADAPTER_LIST *MsCreateAdapterListInnerEx(bool no_info);
+void MsFreeAdapter(MS_ADAPTER *a);
+void MsFreeAdapterList(MS_ADAPTER_LIST *o);
+wchar_t *MsGetAdapterTypeStr(UINT type);
+wchar_t *MsGetAdapterStatusStr(UINT status);
+MS_ADAPTER *MsCloneAdapter(MS_ADAPTER *a);
+MS_ADAPTER_LIST *MsCloneAdapterList(MS_ADAPTER_LIST *o);
+void MsInitAdapterListModule();
+void MsFreeAdapterListModule();
+MS_ADAPTER_LIST *MsCreateAdapterList();
+MS_ADAPTER_LIST *MsCreateAdapterListEx(bool no_info);
+void MsGetAdapterTcpIpInformation(MS_ADAPTER *a);
+MS_ADAPTER *MsGetAdapter(char *title);
+
+void *MsLoadLibrary(char *name);
+void *MsLoadLibraryW(wchar_t *name);
+void *MsLoadLibraryAsDataFile(char *name);
+void *MsLoadLibraryAsDataFileW(wchar_t *name);
+
+void MsPrintTick();
+bool MsDisableIme();
+
+void MsGetTcpConfig(MS_TCP *tcp);
+void MsSetTcpConfig(MS_TCP *tcp);
+void MsSaveTcpConfigReg(MS_TCP *tcp);
+bool MsLoadTcpConfigReg(MS_TCP *tcp);
+bool MsIsTcpConfigSupported();
+void MsApplyTcpConfig();
+bool MsIsShouldShowTcpConfigApp();
+void MsDeleteTcpConfigReg();
+
+UINT MsGetConsoleWidth();
+UINT MsSetConsoleWidth(UINT size);
+NO_WARNING *MsInitNoWarning();
+void MsFreeNoWarning(NO_WARNING *nw);
+void MsNoWarningThreadProc(THREAD *thread, void *param);
+char *MsNoWarningSoundInit();
+void MsNoWarningSoundFree(char *s);
+bool MsCloseWarningWindow(UINT thread_id);
+LIST *MsEnumChildWindows(LIST *o, HWND hWnd);
+void MsAddWindowToList(LIST *o, HWND hWnd);
+UINT MsGetThreadLocale();
+LIST *NewWindowList();
+int CmpWindowList(void *p1, void *p2);
+void AddWindow(LIST *o, HWND hWnd);
+void FreeWindowList(LIST *o);
+LIST *EnumAllChildWindow(HWND hWnd);
+LIST *EnumAllChildWindowEx(HWND hWnd, bool no_recursion, bool include_ipcontrol, bool no_self);
+LIST *EnumAllWindow();
+LIST *EnumAllWindowEx(bool no_recursion, bool include_ipcontrol);
+LIST *EnumAllTopWindow();
+
+bool MsExecDriverInstaller(char *arg);
+bool MsIsVista();
+bool MsIsWin2000();
+bool MsIsWin2000OrGreater();
+void MsRegistWindowsFirewall(char *title);
+void MsRegistWindowsFirewallEx(char *title, char *exe);
+void MsRegistWindowsFirewallEx2(char *title, char *exe);
+bool MsIs64BitWindows();
+bool MsIsX64();
+bool MsIsIA64();
+void *MsDisableWow64FileSystemRedirection();
+void MsRestoreWow64FileSystemRedirection(void *p);
+void MsSetWow64FileSystemRedirectionEnable(bool enable);
+
+bool MsCheckFileDigitalSignature(HWND hWnd, char *name, bool *danger);
+bool MsCheckFileDigitalSignatureW(HWND hWnd, wchar_t *name, bool *danger);
+
+bool MsGetProcessExeName(char *path, UINT size, UINT id);
+bool MsGetProcessExeNameW(wchar_t *path, UINT size, UINT id);
+bool MsGetWindowOwnerProcessExeName(char *path, UINT size, HWND hWnd);
+bool MsGetWindowOwnerProcessExeNameW(wchar_t *path, UINT size, HWND hWnd);
+
+void *MsRunAsUserEx(char *filename, char *arg, bool hide);
+void *MsRunAsUserExW(wchar_t *filename, wchar_t *arg, bool hide);
+void *MsRunAsUserExInner(char *filename, char *arg, bool hide);
+void *MsRunAsUserExInnerW(wchar_t *filename, wchar_t *arg, bool hide);
+
+UINT MsGetCursorPosHash();
+bool MsIsProcessExists(char *exename);
+bool MsIsProcessExistsW(wchar_t *exename);
+
+void MsGetComputerName(char *name, UINT size);
+void MsNoSleepThread(THREAD *thread, void *param);
+void MsNoSleepThreadVista(THREAD *thread, void *param);
+UINT64 MsGetScreenSaverTimeout();
+void *MsNoSleepStart(bool no_screensaver);
+void MsNoSleepEnd(void *p);
+bool MsIsRemoteDesktopAvailable();
+bool MsIsRemoteDesktopCanEnableByRegistory();
+bool MsIsRemoteDesktopEnabled();
+bool MsEnableRemoteDesktop();
+
+void MsSetFileToHidden(char *name);
+void MsSetFileToHiddenW(wchar_t *name);
+bool MsGetFileVersion(char *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4);
+bool MsGetFileVersionW(wchar_t *name, UINT *v1, UINT *v2, UINT *v3, UINT *v4);
+
+bool MsExtractCabinetFileFromExe(char *exe, char *cab);
+bool MsExtractCabinetFileFromExeW(wchar_t *exe, wchar_t *cab);
+BUF *MsExtractResourceFromExe(char *exe, char *type, char *name);
+BUF *MsExtractResourceFromExeW(wchar_t *exe, char *type, char *name);
+bool MsExtractCab(char *cab_name, char *dest_dir_name);
+bool MsExtractCabW(wchar_t *cab_name, wchar_t *dest_dir_name);
+bool MsGetCabarcExeFilename(char *name, UINT size);
+bool MsGetCabarcExeFilenameW(wchar_t *name, UINT size);
+bool MsExtractCabFromMsi(char *msi, char *cab);
+bool MsExtractCabFromMsiW(wchar_t *msi, wchar_t *cab);
+bool MsIsDirectory(char *name);
+bool MsIsDirectoryW(wchar_t *name);
+bool MsUniIsDirectory(wchar_t *name);
+bool MsUniFileDelete(wchar_t *name);
+bool MsUniDirectoryDelete(wchar_t *name);
+bool MsUniMakeDir(wchar_t *name);
+void MsUniMakeDirEx(wchar_t *name);
+void MsMakeDirEx(char *name);
+bool MsMakeDir(char *name);
+bool MsDirectoryDelete(char *name);
+bool MsFileDelete(char *name);
+bool MsExecute(char *exe, char *arg);
+bool MsExecuteW(wchar_t *exe, wchar_t *arg);
+bool MsExecuteEx(char *exe, char *arg, void **process_handle);
+bool MsExecuteExW(wchar_t *exe, wchar_t *arg, void **process_handle);
+UINT MsWaitProcessExit(void *process_handle);
+bool MsIsFileLocked(char *name);
+bool MsIsFileLockedW(wchar_t *name);
+bool MsIsLocalDrive(char *name);
+bool MsIsLocalDriveW(wchar_t *name);
+void MsUpdateSystem();
+bool MsGetPhysicalMacAddressFromNetbios(void *address);
+bool MsGetPhysicalMacAddressFromApi(void *address);
+bool MsGetPhysicalMacAddress(void *address);
+bool MsIsUseWelcomeLogin();
+UINT64 MsGetHiResCounter();
+double MsGetHiResTimeSpan(UINT64 diff);
+UINT64 MsGetHiResTimeSpanUSec(UINT64 diff);
+BUF *MsRegSubkeysToBuf(UINT root, char *keyname, bool force32bit, bool force64bit);
+void MsBufToRegSubkeys(UINT root, char *keyname, BUF *b, bool overwrite, bool force32bit, bool force64bit);
+void MsRegDeleteSubkeys(UINT root, char *keyname, bool force32bit, bool force64bit);
+void MsRestartMMCSS();
+bool MsIsMMCSSNetworkThrottlingEnabled();
+void MsSetMMCSSNetworkThrottlingEnable(bool enable);
+void MsSetShutdownParameters(UINT level, UINT flag);
+void MsChangeIconOnTrayEx2(void *icon, wchar_t *tooltip, wchar_t *info_title, wchar_t *info, UINT info_flags);
+bool MsIsTrayInited();
+UINT MsGetClipboardOwnerProcessId();
+void MsDeleteClipboard();
+void *MsInitEventLog(wchar_t *src_name);
+void MsFreeEventLog(void *p);
+bool MsWriteEventLog(void *p, UINT type, wchar_t *str);
+bool MsIsWinXPOrWinVista();
+bool MsGetFileInformation(void *h, void *info);
+void MsSetErrorModeToSilent();
+void MsSetEnableMinidump(bool enabled);
+void MsWriteMinidump(wchar_t *filename, void *ex);
+
+// 内部関数
+#ifdef	MICROSOFT_C
+
+LONG CALLBACK MsExceptionHandler(struct _EXCEPTION_POINTERS *ExceptionInfo);
+HKEY MsGetRootKeyFromInt(UINT root);
+NT_API *MsLoadNtApiFunctions();
+void MsFreeNtApiFunctions(NT_API *nt);
+void MsDestroyDevInfo(HDEVINFO info);
+HDEVINFO MsGetDevInfoFromDeviceId(SP_DEVINFO_DATA *dev_info_data, char *device_id);
+bool MsStartDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data);
+bool MsStopDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data);
+bool MsDeleteDevice(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data);
+bool MsIsDeviceRunning(HDEVINFO info, SP_DEVINFO_DATA *dev_info_data);
+void CALLBACK MsServiceDispatcher(DWORD argc, LPTSTR *argv);
+void CALLBACK MsServiceHandler(DWORD opcode);
+void MsServiceStoperThread(THREAD *t, void *p);
+void MsServiceStoperMainThread(THREAD *t, void *p);
+void MsServiceStarterMainThread(THREAD *t, void *p);
+LRESULT CALLBACK MsUserModeWindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
+void MsShowIconOnTray(HWND hWnd, HICON icon, wchar_t *tooltip, UINT msg);
+void MsRestoreIconOnTray();
+void MsChangeIconOnTray(HICON icon, wchar_t *tooltip);
+void MsChangeIconOnTrayEx(HICON icon, wchar_t *tooltip, wchar_t *info_title, wchar_t *info, UINT info_flags);
+void MsHideIconOnTray();
+void MsUserModeTrayMenu(HWND hWnd);
+bool MsAppendMenu(HMENU hMenu, UINT flags, UINT_PTR id, wchar_t *str);
+bool MsInsertMenu(HMENU hMenu, UINT pos, UINT flags, UINT_PTR id_new_item, wchar_t *lp_new_item);
+bool CALLBACK MsEnumChildWindowProc(HWND hWnd, LPARAM lParam);
+BOOL CALLBACK EnumTopWindowProc(HWND hWnd, LPARAM lParam);
+bool CALLBACK MsEnumThreadWindowProc(HWND hWnd, LPARAM lParam);
+HANDLE MsCreateUserToken();
+SID *MsGetSidFromAccountName(char *name);
+void MsFreeSid(SID *sid);
+
+#endif	// MICROSOFT_C
+
+#endif	// MICROSOFT_H
+
+#endif	// OS_WIN32
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Network.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Network.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Network.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,9389 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Network.c
+// ネットワーク通信モジュール
+
+#define	ENCRYPT_C
+#define	NETWORK_C
+
+#define	__WINCRYPT_H__
+
+#ifdef	WIN32
+// Socket API のために windows.h をインクルード
+#define	_WIN32_WINNT		0x0502
+#define	WINVER				0x0502
+#include <Ws2tcpip.h>
+#include <Wspiapi.h>
+#include <winsock2.h>
+#include <Ws2tcpip.h>
+#include <windows.h>
+#include <Iphlpapi.h>
+#endif	// WIN32
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/engine.h>
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rc4.h>
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <Mayaqua/Mayaqua.h>
+
+#ifdef	OS_WIN32
+NETWORK_WIN32_FUNCTIONS *w32net;
+struct ROUTE_CHANGE_DATA
+{
+	OVERLAPPED Overlapped;
+	HANDLE Handle;
+	UINT NumCalled;
+};
+#endif	// OS_WIN32
+
+// SSL でブロッキングするかどうか
+#if	defined(UNIX_BSD)
+#define	FIX_SSL_BLOCKING
+#endif
+
+// IPV6_V6ONLY 定数
+#ifdef	UNIX_LINUX
+#ifndef	IPV6_V6ONLY
+#define	IPV6_V6ONLY	26
+#endif	// IPV6_V6ONLY
+#endif	// UNIX_LINUX
+
+#ifdef	UNIX_SOLARIS
+#ifndef	IPV6_V6ONLY
+#define	IPV6_V6ONLY	0x27
+#endif	// IPV6_V6ONLY
+#endif	// UNIX_SOLARIS
+
+// SSL_CTX
+static SSL_CTX *ssl_ctx = NULL;
+
+// DNS キャッシュリスト
+static LIST *DnsCache;
+
+// ロック関係
+static LOCK *machine_name_lock = NULL;
+static LOCK *disconnect_function_lock = NULL;
+static LOCK *aho = NULL;
+static LOCK *socket_library_lock = NULL;
+extern LOCK *openssl_lock;
+static LOCK *ssl_accept_lock = NULL;
+static LOCK *ssl_connect_lock = NULL;
+static TOKEN_LIST *cipher_list_token = NULL;
+static COUNTER *num_tcp_connections = NULL;
+static LOCK *dns_lock = NULL;
+static LOCK *unix_dns_server_addr_lock = NULL;
+static IP unix_dns_server;
+static LIST *HostCacheList = NULL;
+static LIST *WaitThreadList = NULL;
+static bool disable_cache = false;
+static bool NetworkReleaseMode = false;			// ネットワークリリースモード
+
+static char *cipher_list = "RC4-MD5 RC4-SHA AES128-SHA AES256-SHA DES-CBC-SHA DES-CBC3-SHA";
+static LIST *ip_clients = NULL;
+
+// ルーティングテーブル変更検出を初期化
+ROUTE_CHANGE *NewRouteChange()
+{
+#ifdef	OS_WIN32
+	return Win32NewRouteChange();
+#else	// OS_WIN32
+	return NULL;
+#endif	// OS_WIN32
+}
+
+// ルーティングテーブル変更検出を解放
+void FreeRouteChange(ROUTE_CHANGE *r)
+{
+#ifdef	OS_WIN32
+	Win32FreeRouteChange(r);
+#endif	// OS_WIN32
+}
+
+// ルーティングテーブルが変更されたかどうか取得
+bool IsRouteChanged(ROUTE_CHANGE *r)
+{
+#ifdef	OS_WIN32
+	return Win32IsRouteChanged(r);
+#else	// OS_WIN32
+	return false;
+#endif	// OS_WIN32
+}
+
+// ルーティングテーブル変更検出機能 (Win32)
+#ifdef	OS_WIN32
+ROUTE_CHANGE *Win32NewRouteChange()
+{
+	ROUTE_CHANGE *r;
+	bool ret;
+
+	if (MsIsNt() == false)
+	{
+		return NULL;
+	}
+
+	if (w32net->CancelIPChangeNotify == NULL ||
+		w32net->NotifyRouteChange == NULL)
+	{
+		return NULL;
+	}
+
+	r = ZeroMalloc(sizeof(ROUTE_CHANGE));
+
+	r->Data = ZeroMalloc(sizeof(ROUTE_CHANGE_DATA));
+
+	r->Data->Overlapped.hEvent = CreateEventA(NULL, false, true, NULL);
+
+	ret = w32net->NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
+	if (!(ret == NO_ERROR || ret == WSA_IO_PENDING || WSAGetLastError() == WSA_IO_PENDING))
+	{
+		Free(r->Data);
+		Free(r);
+
+		return NULL;
+	}
+
+	return r;
+}
+
+void Win32FreeRouteChange(ROUTE_CHANGE *r)
+{
+	// 引数チェック
+	if (r == NULL)
+	{
+		return;
+	}
+
+	w32net->CancelIPChangeNotify(&r->Data->Overlapped);
+	CloseHandle(r->Data->Overlapped.hEvent);
+
+	Free(r->Data);
+	Free(r);
+}
+
+bool Win32IsRouteChanged(ROUTE_CHANGE *r)
+{
+	// 引数チェック
+	if (r == NULL)
+	{
+		return false;
+	}
+
+	if ((r->Data->NumCalled++) == 0)
+	{
+		return true;
+	}
+
+	if (WaitForSingleObject(r->Data->Overlapped.hEvent, 0) == WAIT_OBJECT_0)
+	{
+		w32net->NotifyRouteChange(&r->Data->Handle, &r->Data->Overlapped);
+		return true;
+	}
+
+	return false;
+}
+
+#endif	// OS_WIN32
+
+
+// TCP コネクションのプロセス ID の取得が成功するかどうかを取得
+bool CanGetTcpProcessId()
+{
+	UINT i;
+	bool ret = false;
+	LIST *o = GetTcpTableList();
+
+	if (o == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		TCPTABLE *t = LIST_DATA(o, i);
+
+		if (t->ProcessId != 0)
+		{
+			ret = true;
+			break;
+		}
+	}
+
+	FreeTcpTableList(o);
+
+	return ret;
+}
+
+
+
+
+#define	USE_OLD_GETIP
+
+// Linux における arp_filter を設定する
+void SetLinuxArpFilter()
+{
+	char *filename = "/proc/sys/net/ipv4/conf/all/arp_filter";
+	char *data = "1\n";
+	IO *o;
+
+	o = FileCreate(filename);
+	if (o == NULL)
+	{
+		return;
+	}
+
+	FileWrite(o, data, StrLen(data));
+	FileFlush(o);
+
+	FileClose(o);
+}
+
+// 指定された文字列が IPv6 マスクかどうか判定する
+bool IsIpMask6(char *str)
+{
+	IP mask;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	return StrToMask6(&mask, str);
+}
+
+// 指定された文字列が IPv6 アドレスかどうか判定する
+bool IsStrIPv6Address(char *str)
+{
+	IP ip;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	if (StrToIP6(&ip, str) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// サブネットマスクを整数に変換する
+UINT SubnetMaskToInt6(IP *a)
+{
+	UINT i;
+	// 引数チェック
+	if (IsIP6(a) == false)
+	{
+		return 0;
+	}
+
+	for (i = 0;i <= 128;i++)
+	{
+		IP tmp;
+
+		IntToSubnetMask6(&tmp, i);
+
+		if (CmpIpAddr(a, &tmp) == 0)
+		{
+			return i;
+		}
+	}
+
+	return 0;
+}
+UINT SubnetMaskToInt4(IP *a)
+{
+	UINT i;
+	// 引数チェック
+	if (IsIP4(a) == false)
+	{
+		return 0;
+	}
+
+	for (i = 0;i <= 32;i++)
+	{
+		IP tmp;
+
+		IntToSubnetMask4(&tmp, i);
+
+		if (CmpIpAddr(a, &tmp) == 0)
+		{
+			return i;
+		}
+	}
+
+	return 0;
+}
+UINT SubnetMaskToInt(IP *a)
+{
+	if (IsIP6(a))
+	{
+		return SubnetMaskToInt6(a);
+	}
+	else
+	{
+		return SubnetMaskToInt4(a);
+	}
+}
+
+// 指定した IP アドレスがサブネットマスクかどうか調べる
+bool IsSubnetMask6(IP *a)
+{
+	UINT i;
+	// 引数チェック
+	if (IsIP6(a) == false)
+	{
+		return false;
+	}
+
+	for (i = 0;i <= 128;i++)
+	{
+		IP tmp;
+
+		IntToSubnetMask6(&tmp, i);
+
+		if (CmpIpAddr(a, &tmp) == 0)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// MAC アドレスからグローバルアドレスを生成する
+void GenerateEui64GlobalAddress(IP *ip, IP *prefix, IP *subnet, UCHAR *mac)
+{
+	UCHAR tmp[8];
+	IP a;
+	IP subnet_not;
+	IP or1, or2;
+	// 引数チェック
+	if (ip == NULL || prefix == NULL || subnet == NULL || mac == NULL)
+	{
+		return;
+	}
+
+	GenerateEui64Address6(tmp, mac);
+
+	ZeroIP6(&a);
+
+	Copy(&a.ipv6_addr[8], tmp, 8);
+
+	IPNot6(&subnet_not, subnet);
+	IPAnd6(&or1, &a, &subnet_not);
+	IPAnd6(&or2, prefix, subnet);
+
+	IPOr6(ip, &or1, &or2);
+}
+
+// MAC アドレスからローカルアドレスを生成する
+void GenerateEui64LocalAddress(IP *a, UCHAR *mac)
+{
+	UCHAR tmp[8];
+	// 引数チェック
+	if (a == NULL || mac == NULL)
+	{
+		return;
+	}
+
+	GenerateEui64Address6(tmp, mac);
+
+	ZeroIP6(a);
+	a->ipv6_addr[0] = 0xfe;
+	a->ipv6_addr[1] = 0x80;
+
+	Copy(&a->ipv6_addr[8], tmp, 8);
+}
+
+// MAC アドレスから EUI-64 アドレスを生成する
+void GenerateEui64Address6(UCHAR *dst, UCHAR *mac)
+{
+	// 引数チェック
+	if (dst == NULL || mac == NULL)
+	{
+		return;
+	}
+
+	Copy(dst, mac, 3);
+	Copy(dst + 5, mac, 3);
+
+	dst[3] = 0xff;
+	dst[4] = 0xfe;
+	dst[0] = ((~(dst[0] & 0x02)) & 0x02) | (dst[0] & 0xfd);
+}
+
+// 同一のネットワークかどうか調べる
+bool IsInSameNetwork6(IP *a1, IP *a2, IP *subnet)
+{
+	IP prefix1, prefix2;
+	// 引数チェック
+	if (IsIP6(a1) == false || IsIP6(a2) == false || IsIP6(subnet) == false)
+	{
+		return false;
+	}
+
+	if (a1->ipv6_scope_id != a2->ipv6_scope_id)
+	{
+		return false;
+	}
+
+	GetPrefixAddress6(&prefix1, a1, subnet);
+	GetPrefixAddress6(&prefix2, a2, subnet);
+
+	if (CmpIpAddr(&prefix1, &prefix2) == 0)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// ネットワークプレフィックスアドレスかどうかチェックする
+bool IsNetworkAddress6(IP *ip, IP *subnet)
+{
+	return IsNetworkPrefixAddress6(ip, subnet);
+}
+bool IsNetworkPrefixAddress6(IP *ip, IP *subnet)
+{
+	IP host;
+	// 引数チェック
+	if (ip == NULL || subnet == NULL)
+	{
+		return false;
+	}
+
+	if (IsIP6(ip) == false || IsIP6(subnet) == false)
+	{
+		return false;
+	}
+
+	GetHostAddress6(&host, ip, subnet);
+
+	if (IsZeroIp(&host))
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// ユニキャストアドレスが有効かどうかチェックする
+bool CheckUnicastAddress(IP *ip)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return false;
+	}
+
+	if ((GetIPAddrType6(ip) & IPV6_ADDR_UNICAST) == 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ホストアドレスの取得
+void GetHostAddress6(IP *dst, IP *ip, IP *subnet)
+{
+	IP not;
+	// 引数チェック
+	if (dst == NULL || ip == NULL || subnet == NULL)
+	{
+		return;
+	}
+
+	IPNot6(&not, subnet);
+
+	IPAnd6(dst, ip, &not);
+
+	dst->ipv6_scope_id = ip->ipv6_scope_id;
+}
+
+// プレフィックスアドレスの取得
+void GetPrefixAddress6(IP *dst, IP *ip, IP *subnet)
+{
+	// 引数チェック
+	if (dst == NULL || ip == NULL || subnet == NULL)
+	{
+		return;
+	}
+
+	IPAnd6(dst, ip, subnet);
+
+	dst->ipv6_scope_id = ip->ipv6_scope_id;
+}
+
+// 要請ノードマルチキャストアドレスを取得
+void GetSoliciationMulticastAddr6(IP *dst, IP *src)
+{
+	IP prefix;
+	IP mask104;
+	IP or1, or2;
+
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return;
+	}
+
+	ZeroIP6(&prefix);
+	prefix.ipv6_addr[0] = 0xff;
+	prefix.ipv6_addr[1] = 0x02;
+	prefix.ipv6_addr[11] = 0x01;
+	prefix.ipv6_addr[12] = 0xff;
+
+	IntToSubnetMask6(&mask104, 104);
+
+	IPAnd6(&or1, &prefix, &mask104);
+	IPAnd6(&or2, src, &mask104);
+
+	IPOr6(dst, &or1, &or2);
+
+	dst->ipv6_scope_id = src->ipv6_scope_id;
+}
+
+// マルチキャストアドレスに対応した MAC アドレスの生成
+void GenerateMulticastMacAddress6(UCHAR *mac, IP *ip)
+{
+	// 引数チェック
+	if (mac == NULL)
+	{
+		return;
+	}
+
+	mac[0] = 0x33;
+	mac[1] = 0x33;
+	mac[2] = ip->ipv6_addr[12];
+	mac[3] = ip->ipv6_addr[13];
+	mac[4] = ip->ipv6_addr[14];
+	mac[5] = ip->ipv6_addr[15];
+}
+
+// IPv6 アドレスのタイプの取得
+UINT GetIPv6AddrType(IPV6_ADDR *addr)
+{
+	IP ip;
+	// 引数チェック
+	if (addr == NULL)
+	{
+		return 0;
+	}
+
+	IPv6AddrToIP(&ip, addr);
+
+	return GetIPAddrType6(&ip);
+}
+UINT GetIPAddrType6(IP *ip)
+{
+	UINT ret = 0;
+	// 引数チェック
+	if (IsIP6(ip) == false)
+	{
+		return 0;
+	}
+
+	if (ip->ipv6_addr[0] == 0xff)
+	{
+		IP all_node, all_router;
+
+		GetAllNodeMulticaseAddress6(&all_node);
+
+		GetAllRouterMulticastAddress6(&all_router);
+
+		ret |= IPV6_ADDR_MULTICAST;
+
+		if (Cmp(ip->ipv6_addr, all_node.ipv6_addr, 16) == 0)
+		{
+			ret |= IPV6_ADDR_ALL_NODE_MULTICAST;
+		}
+		else if (Cmp(ip->ipv6_addr, all_router.ipv6_addr, 16) == 0)
+		{
+			ret |= IPV6_ADDR_ALL_ROUTER_MULTICAST;
+		}
+		else
+		{
+			if (ip->ipv6_addr[1] == 0x02 && ip->ipv6_addr[2] == 0 && ip->ipv6_addr[3] == 0 &&
+				ip->ipv6_addr[4] == 0 && ip->ipv6_addr[5] == 0 && ip->ipv6_addr[6] == 0 &&
+				ip->ipv6_addr[7] == 0 && ip->ipv6_addr[8] == 0 && ip->ipv6_addr[9] == 0 &&
+				ip->ipv6_addr[10] == 0 && ip->ipv6_addr[11] == 0x01 && ip->ipv6_addr[12] == 0xff)
+			{
+				ret |= IPV6_ADDR_SOLICIATION_MULTICAST;
+			}
+		}
+	}
+	else
+	{
+		ret |= IPV6_ADDR_UNICAST;
+
+		if (ip->ipv6_addr[0] == 0xfe && (ip->ipv6_addr[1] & 0xc0) == 0x80)
+		{
+			ret |= IPV6_ADDR_LOCAL_UNICAST;
+		}
+		else
+		{
+			ret |= IPV6_ADDR_GLOBAL_UNICAST;
+
+			if (IsZero(&ip->ipv6_addr, 16))
+			{
+				ret |= IPV6_ADDR_ZERO;
+			}
+			else
+			{
+				IP loopback;
+
+				GetLoopbackAddress6(&loopback);
+
+				if (Cmp(ip->ipv6_addr, loopback.ipv6_addr, 16) == 0)
+				{
+					ret |= IPV6_ADDR_LOOPBACK;
+				}
+			}
+		}
+	}
+
+	return ret;
+}
+
+// すべてのビットが立っているアドレス
+void GetAllFilledAddress6(IP *ip)
+{
+	UINT i;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	ZeroIP6(ip);
+
+	for (i = 0;i < 15;i++)
+	{
+		ip->ipv6_addr[i] = 0xff;
+	}
+}
+
+// ループバックアドレス
+void GetLoopbackAddress6(IP *ip)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	ZeroIP6(ip);
+
+	ip->ipv6_addr[15] = 0x01;
+}
+
+// 全ノードマルチキャストアドレス
+void GetAllNodeMulticaseAddress6(IP *ip)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	ZeroIP6(ip);
+
+	ip->ipv6_addr[0] = 0xff;
+	ip->ipv6_addr[1] = 0x02;
+	ip->ipv6_addr[15] = 0x01;
+}
+
+// 全ルータマルチキャストアドレス
+void GetAllRouterMulticastAddress6(IP *ip)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	ZeroIP6(ip);
+
+	ip->ipv6_addr[0] = 0xff;
+	ip->ipv6_addr[1] = 0x02;
+	ip->ipv6_addr[15] = 0x02;
+}
+
+// IPv6 アドレスの論理演算
+void IPAnd6(IP *dst, IP *a, IP *b)
+{
+	UINT i;
+	// 引数チェック
+	if (dst == NULL || IsIP6(a) == false || IsIP6(b) == false)
+	{
+		return;
+	}
+
+	ZeroIP6(dst);
+	for (i = 0;i < 16;i++)
+	{
+		dst->ipv6_addr[i] = a->ipv6_addr[i] & b->ipv6_addr[i];
+	}
+}
+void IPOr6(IP *dst, IP *a, IP *b)
+{
+	UINT i;
+	// 引数チェック
+	if (dst == NULL || IsIP6(a) == false || IsIP6(b) == false)
+	{
+		return;
+	}
+
+	ZeroIP6(dst);
+	for (i = 0;i < 16;i++)
+	{
+		dst->ipv6_addr[i] = a->ipv6_addr[i] | b->ipv6_addr[i];
+	}
+}
+void IPNot6(IP *dst, IP *a)
+{
+	UINT i;
+	// 引数チェック
+	if (dst == NULL || IsIP6(a) == false)
+	{
+		return;
+	}
+
+	ZeroIP6(dst);
+	for (i = 0;i < 16;i++)
+	{
+		dst->ipv6_addr[i] = ~(a->ipv6_addr[i]);
+	}
+}
+
+// サブネットマスクの作成
+void IntToSubnetMask6(IP *ip, UINT i)
+{
+	UINT j = i / 8;
+	UINT k = i % 8;
+	UINT z;
+	IP a;
+
+	ZeroIP6(&a);
+
+	for (z = 0;z < 16;z++)
+	{
+		if (z < j)
+		{
+			a.ipv6_addr[z] = 0xff;
+		}
+		else if (z == j)
+		{
+			a.ipv6_addr[z] = ~(0xff >> k);
+		}
+	}
+
+	Copy(ip, &a, sizeof(IP));
+}
+
+// IP アドレスを文字列に変換
+void IP6AddrToStr(char *str, UINT size, IPV6_ADDR *addr)
+{
+	// 引数チェック
+	if (str == NULL || addr == NULL)
+	{
+		return;
+	}
+
+	IPToStr6Array(str, size, addr->Value);
+}
+void IPToStr6Array(char *str, UINT size, UCHAR *bytes)
+{
+	IP ip;
+	// 引数チェック
+	if (str == NULL || bytes == NULL)
+	{
+		return;
+	}
+
+	SetIP6(&ip, bytes);
+
+	IPToStr6(str, size, &ip);
+}
+void IPToStr6(char *str, UINT size, IP *ip)
+{
+	char tmp[MAX_SIZE];
+
+	IPToStr6Inner(tmp, ip);
+
+	StrCpy(str, size, tmp);
+}
+void IPToStr6Inner(char *str, IP *ip)
+{
+	UINT i;
+	USHORT values[8];
+	UINT zero_started_index;
+	UINT max_zero_len;
+	UINT max_zero_start;
+	IP a;
+	// 引数チェック
+	if (str == NULL || ip == NULL)
+	{
+		return;
+	}
+
+	Copy(&a, ip, sizeof(IP));
+
+	for (i = 0;i < 8;i++)
+	{
+		Copy(&values[i], &a.ipv6_addr[i * 2], sizeof(USHORT));
+		values[i] = Endian16(values[i]);
+	}
+
+	// 省略できる場所があるかどうか検索
+	zero_started_index = INFINITE;
+	max_zero_len = 0;
+	max_zero_start = INFINITE;
+	for (i = 0;i < 9;i++)
+	{
+		USHORT v = (i != 8 ? values[i] : 1);
+
+		if (values[i] == 0)
+		{
+			if (zero_started_index == INFINITE)
+			{
+				zero_started_index = i;
+			}
+		}
+		else
+		{
+			UINT zero_len;
+
+			if (zero_started_index != INFINITE)
+			{
+				zero_len = i - zero_started_index;
+				if (zero_len >= 2)
+				{
+					if (max_zero_len < zero_len)
+					{
+						max_zero_start = zero_started_index;
+						max_zero_len = zero_len;
+					}
+				}
+
+				zero_started_index = INFINITE;
+			}
+		}
+	}
+
+	// 文字列を形成
+	StrCpy(str, 0, "");
+	for (i = 0;i < 8;i++)
+	{
+		char tmp[16];
+
+		ToHex(tmp, values[i]);
+		StrLower(tmp);
+
+		if (i == max_zero_start)
+		{
+			if (i == 0)
+			{
+				StrCat(str, 0, "::");
+			}
+			else
+			{
+				StrCat(str, 0, ":");
+			}
+			i += max_zero_len - 1;
+		}
+		else
+		{
+			StrCat(str, 0, tmp);
+			if (i != 7)
+			{
+				StrCat(str, 0, ":");
+			}
+		}
+	}
+
+	// スコープ ID
+	if (ip->ipv6_scope_id != 0)
+	{
+		char tmp[64];
+
+		StrCat(str, 0, "%");
+		ToStr(tmp, ip->ipv6_scope_id);
+
+		StrCat(str, 0, tmp);
+	}
+}
+
+// 文字列を IP アドレスに変換
+bool StrToIP6(IP *ip, char *str)
+{
+	TOKEN_LIST *t;
+	char tmp[MAX_PATH];
+	IP a;
+	UINT i;
+	UINT scope_id = 0;
+	// 引数チェック
+	if (str == NULL || ip == NULL)
+	{
+		return false;
+	}
+
+	ZeroIP6(&a);
+
+	StrCpy(tmp, sizeof(tmp), str);
+	Trim(tmp);
+
+	if (StartWith(tmp, "[") && EndWith(tmp, "]"))
+	{
+		// かぎかっこで囲まれている場合はそれを除去
+		StrCpy(tmp, sizeof(tmp), &tmp[1]);
+
+		if (StrLen(tmp) >= 1)
+		{
+			tmp[StrLen(tmp) - 1] = 0;
+		}
+	}
+
+	// スコープ ID がある場合はそれを解析して除去
+	i = SearchStrEx(tmp, "%", 0, false);
+	if (i != INFINITE)
+	{
+		char ss[MAX_PATH];
+
+		StrCpy(ss, sizeof(ss), &tmp[i + 1]);
+
+		tmp[i] = 0;
+
+		Trim(tmp);
+
+		Trim(ss);
+
+		scope_id = ToInt(ss);
+	}
+
+	// トークン分割
+	t = ParseTokenWithNullStr(tmp, ":");
+	if (t->NumTokens >= 3 && t->NumTokens <= 8)
+	{
+		UINT i, n;
+		bool b = true;
+		UINT k = 0;
+
+		n = 0;
+
+		for (i = 0;i < t->NumTokens;i++)
+		{
+			char *str = t->Token[i];
+
+			if (i != 0 && i != (t->NumTokens - 1) && StrLen(str) == 0)
+			{
+				n++;
+				if (n == 1)
+				{
+					k += 2 * (8 - t->NumTokens + 1);
+				}
+				else
+				{
+					b = false;
+					break;
+				}
+			}
+			else
+			{
+				UCHAR chars[2];
+
+				if (CheckIPItemStr6(str) == false)
+				{
+					b = false;
+					break;
+				}
+
+				IPItemStrToChars6(chars, str);
+
+				a.ipv6_addr[k++] = chars[0];
+				a.ipv6_addr[k++] = chars[1];
+			}
+		}
+
+		if (n != 0 && n != 1)
+		{
+			b = false;
+		}
+		else if (n == 0 && t->NumTokens != 8)
+		{
+			b = false;
+		}
+
+		if (b == false)
+		{
+			FreeToken(t);
+			return false;
+		}
+	}
+	else
+	{
+		FreeToken(t);
+		return false;
+	}
+
+	FreeToken(t);
+
+	Copy(ip, &a, sizeof(IP));
+
+	ip->ipv6_scope_id = scope_id;
+
+	return true;
+}
+bool StrToIP6Addr(IPV6_ADDR *ip, char *str)
+{
+	IP ip2;
+	// 引数チェック
+	if (ip == NULL || str == NULL)
+	{
+		Zero(ip, sizeof(IPV6_ADDR));
+		return false;
+	}
+
+	if (StrToIP6(&ip2, str) == false)
+	{
+		return false;
+	}
+
+	if (IPToIPv6Addr(ip, &ip2) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// IP アドレスの文字から UCHAR 型に変換
+void IPItemStrToChars6(UCHAR *chars, char *str)
+{
+	char tmp[5];
+	BUF *b;
+	UINT len;
+	// 引数チェック
+	if (chars == NULL)
+	{
+		return;
+	}
+
+	Zero(tmp, sizeof(tmp));
+
+	len = StrLen(str);
+	switch (len)
+	{
+	case 0:
+		tmp[0] = tmp[1] = tmp[2] = tmp[3] = '0';
+		break;
+
+	case 1:
+		tmp[0] = tmp[1] = tmp[2] = '0';
+		tmp[3] = str[0];
+		break;
+
+	case 2:
+		tmp[0] = tmp[1] = '0';
+		tmp[2] = str[0];
+		tmp[3] = str[1];
+		break;
+
+	case 3:
+		tmp[0] = '0';
+		tmp[1] = str[0];
+		tmp[2] = str[1];
+		tmp[3] = str[2];
+		break;
+
+	case 4:
+		tmp[0] = str[0];
+		tmp[1] = str[1];
+		tmp[2] = str[2];
+		tmp[3] = str[3];
+		break;
+	}
+
+	b = StrToBin(tmp);
+
+	chars[0] = ((UCHAR *)b->Buf)[0];
+	chars[1] = ((UCHAR *)b->Buf)[1];
+
+	FreeBuf(b);
+}
+
+// IP アドレスの要素文字列の中に不正な文字が含まれていないかどうかチェックする
+bool CheckIPItemStr6(char *str)
+{
+	UINT i, len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	len = StrLen(str);
+	if (len >= 5)
+	{
+		// 長さ不正
+		return false;
+	}
+
+	for (i = 0;i < len;i++)
+	{
+		char c = str[i];
+
+		if ((c >= 'a' && c <= 'f') ||
+			(c >= 'A' && c <= 'F') ||
+			(c >= '0' && c <= '9'))
+		{
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// ゼロの IPv4 アドレスを作成する
+void ZeroIP4(IP *ip)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	Zero(ip, sizeof(IP));
+}
+
+// ゼロの IPv6 アドレスを作成する
+void ZeroIP6(IP *ip)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	SetIP6(ip, NULL);
+}
+
+// localhost の IP アドレスを取得する
+void GetLocalHostIP6(IP *ip)
+{
+	ZeroIP6(ip);
+
+	ip->ipv6_addr[15] = 1;
+}
+
+// IPV6_ADDR を IP に変換
+void IPv6AddrToIP(IP *ip, IPV6_ADDR *addr)
+{
+	// 引数チェック
+	if (ip == NULL || addr == NULL)
+	{
+		return;
+	}
+
+	SetIP6(ip, addr->Value);
+}
+
+// IP を IPV6_ADDR に変換
+bool IPToIPv6Addr(IPV6_ADDR *addr, IP *ip)
+{
+	UINT i;
+	// 引数チェック
+	if (addr == NULL || ip == NULL)
+	{
+		Zero(addr, sizeof(IPV6_ADDR));
+		return false;
+	}
+
+	if (IsIP6(ip) == false)
+	{
+		Zero(addr, sizeof(IPV6_ADDR));
+		return false;
+	}
+
+	for (i = 0;i < 16;i++)
+	{
+		addr->Value[i] = ip->ipv6_addr[i];
+	}
+
+	return true;
+}
+
+// IPv6 アドレスをセットする
+void SetIP6(IP *ip, UCHAR *value)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	Zero(ip, sizeof(IP));
+
+	ip->addr[0] = 223;
+	ip->addr[1] = 255;
+	ip->addr[2] = 255;
+	ip->addr[3] = 254;
+
+	if (value != NULL)
+	{
+		UINT i;
+
+		for (i = 0;i < 16;i++)
+		{
+			ip->ipv6_addr[i] = value[i];
+		}
+	}
+}
+
+// 指定されたアドレスが IPv6 アドレスかどうかチェックする
+bool IsIP6(IP *ip)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return false;
+	}
+
+	if (ip->addr[0] == 223 && ip->addr[1] == 255 && ip->addr[2] == 255 && ip->addr[3] == 254)
+	{
+		return true;
+	}
+
+	return false;
+}
+bool IsIP4(IP *ip)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return false;
+	}
+
+	return (IsIP6(ip) ? false : true);
+}
+
+// IPv6 のサブネット長をチェック
+bool CheckSubnetLength6(UINT i)
+{
+	if (i >= 1 && i <= 127)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// ソケットから対応する TCP コネクションのプロセス ID を取得
+UINT GetTcpProcessIdFromSocket(SOCK *s)
+{
+	LIST *o;
+	TCPTABLE *t;
+	UINT pid = 0;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return 0;
+	}
+
+	o = GetTcpTableList();
+	if (o == NULL)
+	{
+		return 0;
+	}
+
+	t = GetTcpTableFromEndPoint(o, &s->LocalIP, s->LocalPort,
+		&s->RemoteIP, s->RemotePort);
+
+	if (t != NULL)
+	{
+		pid = t->ProcessId;
+	}
+
+	FreeTcpTableList(o);
+
+	return pid;
+}
+UINT GetTcpProcessIdFromSocketReverse(SOCK *s)
+{
+	LIST *o;
+	TCPTABLE *t;
+	UINT pid = 0;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return 0;
+	}
+
+	o = GetTcpTableList();
+	if (o == NULL)
+	{
+		return 0;
+	}
+
+	t = GetTcpTableFromEndPoint(o, &s->RemoteIP, s->RemotePort,
+		&s->LocalIP, s->LocalPort);
+
+	if (t != NULL)
+	{
+		pid = t->ProcessId;
+	}
+
+	FreeTcpTableList(o);
+
+	return pid;
+}
+
+// エンドポイントから TCP テーブルを検索
+TCPTABLE *GetTcpTableFromEndPoint(LIST *o, IP *local_ip, UINT local_port, IP *remote_ip, UINT remote_port)
+{
+	IP local;
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	SetIP(&local, 127, 0, 0, 1);
+
+	if (local_ip == NULL)
+	{
+		local_ip = &local;
+	}
+
+	if (remote_ip == NULL)
+	{
+		remote_ip = &local;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		TCPTABLE *t = LIST_DATA(o, i);
+
+		if (t->Status == TCP_STATE_SYN_SENT || t->Status == TCP_STATE_SYN_RCVD ||
+			t->Status == TCP_STATE_ESTAB)
+		{
+			if (CmpIpAddr(&t->LocalIP, local_ip) == 0)
+			{
+				if (CmpIpAddr(&t->RemoteIP, remote_ip) == 0)
+				{
+					if (t->LocalPort == local_port)
+					{
+						if (t->RemotePort == remote_port)
+						{
+							return t;
+						}
+					}
+				}
+			}
+		}
+	}
+
+	return NULL;
+}
+
+// TCP テーブルリストを取得 (Win32)
+#ifdef	OS_WIN32
+LIST *Win32GetTcpTableList()
+{
+	LIST *o;
+
+	// Windows XP SP2 以降用
+	o = Win32GetTcpTableListByGetExtendedTcpTable();
+	if (o != NULL)
+	{
+		return o;
+	}
+
+	// Windows XP 以降用
+	o = Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack();
+	if (o != NULL)
+	{
+		return o;
+	}
+
+	// 古い Windows 用
+	return Win32GetTcpTableListByGetTcpTable();
+}
+
+// TCP テーブルリストを取得: Windows XP SP2 以降用
+LIST *Win32GetTcpTableListByGetExtendedTcpTable()
+{
+	UINT need_size;
+	UINT i;
+	MIB_TCPTABLE_OWNER_PID *table;
+	bool ok = false;
+	LIST *o;
+	if (w32net->GetExtendedTcpTable == NULL)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < 128;i++)
+	{
+		UINT ret;
+		table = MallocFast(sizeof(MIB_TCPTABLE_OWNER_PID));
+		need_size = sizeof(MIB_TCPTABLE_OWNER_PID);
+		ret = w32net->GetExtendedTcpTable(table, &need_size, true, AF_INET, _TCP_TABLE_OWNER_PID_ALL, 0);
+		if (ret == NO_ERROR)
+		{
+			ok = true;
+			break;
+		}
+		else
+		{
+			Free(table);
+			if (ret != ERROR_INSUFFICIENT_BUFFER)
+			{
+				return NULL;
+			}
+		}
+
+		table = MallocFast(need_size);
+
+		ret = w32net->GetExtendedTcpTable(table, &need_size, true, AF_INET, _TCP_TABLE_OWNER_PID_ALL, 0);
+		if (ret == NO_ERROR)
+		{
+			ok = true;
+			break;
+		}
+		else
+		{
+			Free(table);
+
+			if (ret != ERROR_INSUFFICIENT_BUFFER)
+			{
+				return NULL;
+			}
+		}
+	}
+
+	if (ok == false)
+	{
+		return NULL;
+	}
+
+	o = NewListEx(NULL, true);
+
+	for (i = 0;i < table->dwNumEntries;i++)
+	{
+		MIB_TCPROW_OWNER_PID *r = &table->table[i];
+		TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
+
+		UINTToIP(&t->LocalIP, r->dwLocalAddr);
+		t->LocalPort = Endian16((USHORT)r->dwLocalPort);
+
+		if (r->dwState != TCP_STATE_LISTEN)
+		{
+			UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
+			t->RemotePort = Endian16((USHORT)r->dwRemotePort);
+		}
+
+		t->Status = r->dwState;
+		t->ProcessId = r->dwOwningPid;
+
+		Add(o, t);
+	}
+
+	Free(table);
+
+	return o;
+}
+
+// TCP テーブルリストを取得: Windows XP 以降用
+LIST *Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack()
+{
+	HANDLE heap;
+	UINT i;
+	MIB_TCPTABLE_OWNER_PID *table;
+	bool ok = false;
+	LIST *o;
+	if (w32net->AllocateAndGetTcpExTableFromStack == NULL)
+	{
+		return NULL;
+	}
+
+	heap = GetProcessHeap();
+
+	if (w32net->AllocateAndGetTcpExTableFromStack(&table, true, heap, HEAP_GROWABLE, AF_INET) != ERROR_SUCCESS)
+	{
+		return NULL;
+	}
+
+	o = NewListEx(NULL, true);
+
+	for (i = 0;i < table->dwNumEntries;i++)
+	{
+		MIB_TCPROW_OWNER_PID *r = &table->table[i];
+		TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
+
+		UINTToIP(&t->LocalIP, r->dwLocalAddr);
+		t->LocalPort = Endian16((USHORT)r->dwLocalPort);
+
+		if (r->dwState != TCP_STATE_LISTEN)
+		{
+			UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
+			t->RemotePort = Endian16((USHORT)r->dwRemotePort);
+		}
+
+		t->ProcessId = r->dwOwningPid;
+		t->Status = r->dwState;
+
+		Add(o, t);
+	}
+
+	HeapFree(heap, 0, table);
+
+	return o;
+}
+
+// TCP テーブルリストを取得: 古い Windows 用
+LIST *Win32GetTcpTableListByGetTcpTable()
+{
+	UINT need_size;
+	UINT i;
+	MIB_TCPTABLE *table;
+	bool ok = false;
+	LIST *o;
+	if (w32net->GetTcpTable == NULL)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < 128;i++)
+	{
+		UINT ret;
+		table = MallocFast(sizeof(MIB_TCPTABLE));
+		need_size = sizeof(MIB_TCPTABLE);
+		ret = w32net->GetTcpTable(table, &need_size, true);
+		if (ret == NO_ERROR)
+		{
+			ok = true;
+			break;
+		}
+		else
+		{
+			Free(table);
+			if (ret != ERROR_INSUFFICIENT_BUFFER)
+			{
+				return NULL;
+			}
+		}
+
+		table = MallocFast(need_size);
+
+		ret = w32net->GetTcpTable(table, &need_size, true);
+		if (ret == NO_ERROR)
+		{
+			ok = true;
+			break;
+		}
+		else
+		{
+			Free(table);
+
+			if (ret != ERROR_INSUFFICIENT_BUFFER)
+			{
+				return NULL;
+			}
+		}
+	}
+
+	if (ok == false)
+	{
+		return NULL;
+	}
+
+	o = NewListEx(NULL, true);
+
+	for (i = 0;i < table->dwNumEntries;i++)
+	{
+		MIB_TCPROW *r = &table->table[i];
+		TCPTABLE *t = ZeroMallocFast(sizeof(TCPTABLE));
+
+		UINTToIP(&t->LocalIP, r->dwLocalAddr);
+		t->LocalPort = Endian16((USHORT)r->dwLocalPort);
+
+		if (r->dwState != TCP_STATE_LISTEN)
+		{
+			UINTToIP(&t->RemoteIP, r->dwRemoteAddr);
+			t->RemotePort = Endian16((USHORT)r->dwRemotePort);
+		}
+
+		t->Status = r->dwState;
+
+		Add(o, t);
+	}
+
+	Free(table);
+
+	return o;
+}
+
+#endif	// OS_WIN32
+
+// TCP テーブルの表示
+void PrintTcpTableList(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		Print("o == NULL\n\n");
+		return;
+	}
+
+	Print("--- TCPTABLE: %u Entries ---\n", LIST_NUM(o));
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		char tmp1[MAX_PATH], tmp2[MAX_PATH];
+		TCPTABLE *t = LIST_DATA(o, i);
+
+		IPToStr(tmp1, sizeof(tmp1), &t->LocalIP);
+		IPToStr(tmp2, sizeof(tmp2), &t->RemoteIP);
+
+		Print("%s:%u <--> %s:%u  state=%u  pid=%u\n",
+			tmp1, t->LocalPort,
+			tmp2, t->RemotePort,
+			t->Status,
+			t->ProcessId);
+	}
+	Print("------\n\n");
+}
+
+// TCP テーブルの比較
+int CompareTcpTable(void *p1, void *p2)
+{
+	TCPTABLE *t1, *t2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	t1 = *(TCPTABLE **)p1;
+	t2 = *(TCPTABLE **)p2;
+	if (t1 == NULL || t2 == NULL)
+	{
+		return 0;
+	}
+
+	return Cmp(t1, t2, sizeof(TCPTABLE));
+}
+
+// TCP テーブルリストを取得
+LIST *GetTcpTableList()
+{
+#ifdef	OS_WIN32
+	return Win32GetTcpTableList();
+#else	// OS_WIN32
+	return NULL;
+#endif	// OS_WIN32
+}
+
+// TCP テーブルリストを解放
+void FreeTcpTableList(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		TCPTABLE *t = LIST_DATA(o, i);
+
+		Free(t);
+	}
+
+	ReleaseList(o);
+}
+
+// 指定された IP アドレスから接続中のクライアント数の取得
+UINT GetNumIpClient(IP *ip)
+{
+	IP_CLIENT *c;
+	UINT ret = 0;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return 0;
+	}
+
+	LockList(ip_clients);
+	{
+		c = SearchIpClient(ip);
+
+		if (c != NULL)
+		{
+			ret = c->NumConnections;
+		}
+	}
+	UnlockList(ip_clients);
+
+	return ret;
+}
+
+// IP クライアントエントリに追加
+void AddIpClient(IP *ip)
+{
+	IP_CLIENT *c;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	LockList(ip_clients);
+	{
+		c = SearchIpClient(ip);
+
+		if (c == NULL)
+		{
+			c = ZeroMallocFast(sizeof(IP_CLIENT));
+			Copy(&c->IpAddress, ip, sizeof(IP));
+			c->NumConnections = 0;
+
+			Add(ip_clients, c);
+		}
+
+		c->NumConnections++;
+	}
+	UnlockList(ip_clients);
+}
+
+// IP クライアントリストから削除
+void DelIpClient(IP *ip)
+{
+	IP_CLIENT *c;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	LockList(ip_clients);
+	{
+		c = SearchIpClient(ip);
+
+		if (c != NULL)
+		{
+			c->NumConnections--;
+
+			if (c->NumConnections == 0)
+			{
+				Delete(ip_clients, c);
+				Free(c);
+			}
+		}
+	}
+	UnlockList(ip_clients);
+}
+
+// IP クライアントエントリの検索
+IP_CLIENT *SearchIpClient(IP *ip)
+{
+	IP_CLIENT t;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return NULL;
+	}
+
+	Zero(&t, sizeof(t));
+	Copy(&t.IpAddress, ip, sizeof(IP));
+
+	return Search(ip_clients, &t);
+}
+
+// クライアントリストの初期化
+void InitIpClientList()
+{
+	ip_clients = NewList(CompareIpClientList);
+}
+
+// クライアントリストの解放
+void FreeIpClientList()
+{
+	UINT i;
+
+	for (i = 0;i < LIST_NUM(ip_clients);i++)
+	{
+		IP_CLIENT *c = LIST_DATA(ip_clients, i);
+
+		Free(c);
+	}
+
+	ReleaseList(ip_clients);
+	ip_clients = NULL;
+}
+
+// クライアントリストエントリの比較
+int CompareIpClientList(void *p1, void *p2)
+{
+	IP_CLIENT *c1, *c2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	c1 = *(IP_CLIENT **)p1;
+	c2 = *(IP_CLIENT **)p2;
+	if (c1 == NULL || c2 == NULL)
+	{
+		return 0;
+	}
+
+	return CmpIpAddr(&c1->IpAddress, &c2->IpAddress);
+}
+
+// MAC アドレスの正規化
+bool NormalizeMacAddress(char *dst, UINT size, char *src)
+{
+	BUF *b;
+	bool ret = false;
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return false;
+	}
+
+	b = StrToBin(src);
+
+	if (b != NULL && b->Size == 6)
+	{
+		ret = true;
+
+		BinToStr(dst, size, b->Buf, b->Size);
+	}
+
+	FreeBuf(b);
+
+	return ret;
+}
+
+// IP アドレスが空かどうか識別する
+bool IsZeroIP(IP *ip)
+{
+	return IsZeroIp(ip);
+}
+bool IsZeroIp(IP *ip)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return true;
+	}
+
+	if (IsIP6(ip) == false)
+	{
+		return IsZero(ip->addr, sizeof(ip->addr));
+	}
+	else
+	{
+		return IsZero(ip->ipv6_addr, sizeof(ip->ipv6_addr));
+	}
+}
+bool IsZeroIP6Addr(IPV6_ADDR *addr)
+{
+	// 引数チェック
+	if (addr == NULL)
+	{
+		return true;
+	}
+
+	return IsZero(addr, sizeof(IPV6_ADDR));
+}
+
+// 指定された IP アドレスがホストとして意味があるかどうかを調べる
+bool IsHostIPAddress4(IP *ip)
+{
+	UINT a;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return false;
+	}
+
+	a = IPToUINT(ip);
+
+	if (a == 0 || a == 0xffffffff)
+	{
+		return false;
+	}
+
+	return true;
+}
+bool IsHostIPAddress32(UINT ip)
+{
+	IP p;
+
+	UINTToIP(&p, ip);
+
+	return IsHostIPAddress4(&p);
+}
+
+// 指定された IP アドレスとサブネットマスクが正しくネットワークを示すかどうか調べる
+bool IsNetworkAddress(IP *ip, IP *mask)
+{
+	if (IsIP4(ip))
+	{
+		return IsNetworkAddress4(ip, mask);
+	}
+	else
+	{
+		return IsNetworkAddress6(ip, mask);
+	}
+}
+bool IsNetworkAddress4(IP *ip, IP *mask)
+{
+	UINT a, b;
+	// 引数チェック
+	if (ip == NULL || mask == NULL)
+	{
+		return false;
+	}
+
+	if (IsIP4(ip) == false || IsIP4(mask) == false)
+	{
+		return false;
+	}
+
+	if (IsSubnetMask4(mask) == false)
+	{
+		return false;
+	}
+
+	a = IPToUINT(ip);
+	b = IPToUINT(mask);
+
+	if ((a & b) == a)
+	{
+		return true;
+	}
+
+	return false;
+}
+bool IsNetworkAddress32(UINT ip, UINT mask)
+{
+	IP a, b;
+
+	UINTToIP(&a, ip);
+	UINTToIP(&b, mask);
+
+	return IsNetworkAddress4(&a, &b);
+}
+
+// 整数をサブネットマスクに変換する
+UINT IntToSubnetMask32(UINT i)
+{
+	UINT ret = 0xFFFFFFFF;
+
+	// 汚いコード
+	switch (i)
+	{
+	case 0:		ret = 0x00000000;	break;
+	case 1:		ret = 0x80000000;	break;
+	case 2:		ret = 0xC0000000;	break;
+	case 3:		ret = 0xE0000000;	break;
+	case 4:		ret = 0xF0000000;	break;
+	case 5:		ret = 0xF8000000;	break;
+	case 6:		ret = 0xFC000000;	break;
+	case 7:		ret = 0xFE000000;	break;
+	case 8:		ret = 0xFF000000;	break;
+	case 9:		ret = 0xFF800000;	break;
+	case 10:	ret = 0xFFC00000;	break;
+	case 11:	ret = 0xFFE00000;	break;
+	case 12:	ret = 0xFFF00000;	break;
+	case 13:	ret = 0xFFF80000;	break;
+	case 14:	ret = 0xFFFC0000;	break;
+	case 15:	ret = 0xFFFE0000;	break;
+	case 16:	ret = 0xFFFF0000;	break;
+	case 17:	ret = 0xFFFF8000;	break;
+	case 18:	ret = 0xFFFFC000;	break;
+	case 19:	ret = 0xFFFFE000;	break;
+	case 20:	ret = 0xFFFFF000;	break;
+	case 21:	ret = 0xFFFFF800;	break;
+	case 22:	ret = 0xFFFFFC00;	break;
+	case 23:	ret = 0xFFFFFE00;	break;
+	case 24:	ret = 0xFFFFFF00;	break;
+	case 25:	ret = 0xFFFFFF80;	break;
+	case 26:	ret = 0xFFFFFFC0;	break;
+	case 27:	ret = 0xFFFFFFE0;	break;
+	case 28:	ret = 0xFFFFFFF0;	break;
+	case 29:	ret = 0xFFFFFFF8;	break;
+	case 30:	ret = 0xFFFFFFFC;	break;
+	case 31:	ret = 0xFFFFFFFE;	break;
+	case 32:	ret = 0xFFFFFFFF;	break;
+	}
+
+	if (IsLittleEndian())
+	{
+		ret = Swap32(ret);
+	}
+
+	return ret;
+}
+void IntToSubnetMask4(IP *ip, UINT i)
+{
+	UINT m;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	m = IntToSubnetMask32(i);
+
+	UINTToIP(ip, m);
+}
+
+// 指定された IP アドレスがサブネットマスクかどうか調べる
+bool IsSubnetMask(IP *ip)
+{
+	if (IsIP6(ip))
+	{
+		return IsSubnetMask6(ip);
+	}
+	else
+	{
+		return IsSubnetMask4(ip);
+	}
+}
+bool IsSubnetMask4(IP *ip)
+{
+	UINT i;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return false;
+	}
+
+	if (IsIP6(ip))
+	{
+		return false;
+	}
+
+	i = IPToUINT(ip);
+
+	if (IsLittleEndian())
+	{
+		i = Swap32(i);
+	}
+
+	// 汚いコード
+	switch (i)
+	{
+	case 0x00000000:
+	case 0x80000000:
+	case 0xC0000000:
+	case 0xE0000000:
+	case 0xF0000000:
+	case 0xF8000000:
+	case 0xFC000000:
+	case 0xFE000000:
+	case 0xFF000000:
+	case 0xFF800000:
+	case 0xFFC00000:
+	case 0xFFE00000:
+	case 0xFFF00000:
+	case 0xFFF80000:
+	case 0xFFFC0000:
+	case 0xFFFE0000:
+	case 0xFFFF0000:
+	case 0xFFFF8000:
+	case 0xFFFFC000:
+	case 0xFFFFE000:
+	case 0xFFFFF000:
+	case 0xFFFFF800:
+	case 0xFFFFFC00:
+	case 0xFFFFFE00:
+	case 0xFFFFFF00:
+	case 0xFFFFFF80:
+	case 0xFFFFFFC0:
+	case 0xFFFFFFE0:
+	case 0xFFFFFFF0:
+	case 0xFFFFFFF8:
+	case 0xFFFFFFFC:
+	case 0xFFFFFFFE:
+	case 0xFFFFFFFF:
+		return true;
+	}
+
+	return false;
+}
+bool IsSubnetMask32(UINT ip)
+{
+	IP p;
+
+	UINTToIP(&p, ip);
+
+	return IsSubnetMask4(&p);
+}
+
+// ネットワークリリースモード
+void SetNetworkReleaseMode()
+{
+	NetworkReleaseMode = true;
+}
+
+#ifdef	OS_UNIX			// UNIX 用コード
+
+// ソケットをノンブロッキングモードにしたり解除したりする
+void UnixSetSocketNonBlockingMode(int fd, bool nonblock)
+{
+	UINT flag = 0;
+	// 引数チェック
+	if (fd == INVALID_SOCKET)
+	{
+		return;
+	}
+
+	if (nonblock)
+	{
+		flag = 1;
+	}
+
+#ifdef	FIONBIO
+	ioctl(fd, FIONBIO, &flag);
+#else	// FIONBIO
+	{
+		int flag = fcntl(fd, F_GETFL, 0);
+		if (flag != -1)
+		{
+			if (nonblock)
+			{
+				flag |= O_NONBLOCK;
+			}
+			else
+			{
+				flag = flag & ~O_NONBLOCK;
+
+				fcntl(fd, F_SETFL, flag);
+			}
+		}
+	}
+#endif	// FIONBIO
+}
+
+// 何もしない
+void UnixIpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
+{
+}
+
+// 何もしない
+void UnixRouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
+{
+}
+
+// 何もしない
+int UnixCompareRouteEntryByMetric(void *p1, void *p2)
+{
+	return 1;
+}
+
+// 何もしない
+ROUTE_TABLE *UnixGetRouteTable()
+{
+	ROUTE_TABLE *ret = ZeroMalloc(sizeof(ROUTE_TABLE));
+	ret->NumEntry = 0;
+	ret->Entry = ZeroMalloc(0);
+
+	return ret;
+}
+
+// 何もしない
+bool UnixAddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
+{
+	return true;
+}
+
+// 何もしない
+void UnixDeleteRouteEntry(ROUTE_ENTRY *e)
+{
+	return;
+}
+
+// 何もしない
+UINT UnixGetVLanInterfaceID(char *instance_name)
+{
+	return 1;
+}
+
+// 何もしない
+char **UnixEnumVLan(char *tag_name)
+{
+	char **list;
+
+	list = ZeroMalloc(sizeof(char *));
+
+	return list;
+}
+
+// 何もしない
+void UnixRenewDhcp()
+{
+}
+
+// デフォルトの DNS サーバーの IP アドレスを取得
+bool UnixGetDefaultDns(IP *ip)
+{
+	BUF *b;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return false;
+	}
+
+	Lock(unix_dns_server_addr_lock);
+	{
+		if (IsZero(&unix_dns_server, sizeof(IP)) == false)
+		{
+			Copy(ip, &unix_dns_server, sizeof(IP));
+			Unlock(unix_dns_server_addr_lock);
+			return true;
+		}
+
+		ip->addr[0] = 127;
+		ip->addr[1] = 0;
+		ip->addr[2] = 0;
+		ip->addr[3] = 1;
+
+		b = ReadDump("/etc/resolv.conf");
+		if (b != NULL)
+		{
+			char *s;
+			bool f = false;
+			while ((s = CfgReadNextLine(b)) != NULL)
+			{
+				TOKEN_LIST *t = ParseToken(s, "\" \t,");
+				if (t->NumTokens == 2)
+				{
+					if (StrCmpi(t->Token[0], "nameserver") == 0)
+					{
+						StrToIP(ip, t->Token[1]);
+						f = true;
+					}
+				}
+				FreeToken(t);
+
+				Free(s);
+
+				if (f)
+				{
+					break;
+				}
+			}
+			FreeBuf(b);
+		}
+		Copy(&unix_dns_server, ip, sizeof(IP));
+	}
+	Unlock(unix_dns_server_addr_lock);
+
+	return true;
+}
+
+
+// Select 処理
+void UnixSelect(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
+{
+	UINT reads[MAXIMUM_WAIT_OBJECTS];
+	UINT writes[MAXIMUM_WAIT_OBJECTS];
+	UINT num_read, num_write, i;
+	UINT p1, p2;
+	SOCK *s;
+	UCHAR tmp[MAX_SIZE];
+	// 引数チェック
+	if (timeout == 0)
+	{
+		return;
+	}
+
+	// 配列の初期化
+	Zero(reads, sizeof(reads));
+	Zero(writes, sizeof(writes));
+	num_read = num_write = 0;
+
+	// イベント配列の設定
+	if (set != NULL)
+	{
+		for (i = 0;i < set->NumSocket;i++)
+		{
+			s = set->Sock[i];
+			if (s != NULL)
+			{
+				UnixInitAsyncSocket(s);
+				reads[num_read++] = s->socket;
+				if (s->WriteBlocked)
+				{
+					writes[num_write++] = s->socket;
+				}
+			}
+		}
+	}
+
+	p1 = p2 = -1;
+
+	if (c1 != NULL)
+	{
+		reads[num_read++] = p1 = c1->pipe_read;
+	}
+	if (c2 != NULL)
+	{
+		reads[num_read++] = p2 = c2->pipe_read;
+	}
+
+	// select を呼び出す
+	UnixSelectInner(num_read, reads, num_write, writes, timeout);
+
+	// pipe から読んでおく
+	if (c1 != NULL && c1->SpecialFlag == false && p1 != -1)
+	{
+		read(p1, tmp, sizeof(tmp));
+	}
+	if (c2 != NULL && c2->SpecialFlag == false && p2 != -1)
+	{
+		read(p2, tmp, sizeof(tmp));
+	}
+}
+
+// キャンセル
+void UnixCancel(CANCEL *c)
+{
+	// 引数チェック
+	if (c == NULL)
+	{
+		return;
+	}
+
+	UnixWritePipe(c->pipe_write);
+}
+
+// キャンセルオブジェクトの解放
+void UnixCleanupCancel(CANCEL *c)
+{
+	// 引数チェック
+	if (c == NULL)
+	{
+		return;
+	}
+
+	if (c->SpecialFlag == false)
+	{
+		UnixDeletePipe(c->pipe_read, c->pipe_write);
+	}
+
+	Free(c);
+}
+
+// 新しいキャンセルオブジェクトの作成
+CANCEL *UnixNewCancel()
+{
+	CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
+
+	c->ref = NewRef();
+	c->SpecialFlag = false;
+
+	UnixNewPipe(&c->pipe_read, &c->pipe_write);
+
+	return c;
+}
+
+// ソケットをソケットイベントに追加する
+void UnixJoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
+{
+	// 引数チェック
+	if (sock == NULL || event == NULL || sock->AsyncMode)
+	{
+		return;
+	}
+	if (sock->ListenMode != false || (sock->Type == SOCK_TCP && sock->Connected == false))
+	{
+		return;
+	}
+
+	sock->AsyncMode = true;
+
+	LockList(event->SockList);
+	{
+		Add(event->SockList, sock);
+		AddRef(sock->ref);
+	}
+	UnlockList(event->SockList);
+
+	// ソケットを非同期にする
+	UnixSetSocketNonBlockingMode(sock->socket, true);
+
+	// SOCK_EVENT の参照カウンタを増加
+	AddRef(event->ref);
+	sock->SockEvent = event;
+
+	// ソケットイベントを叩く
+	SetSockEvent(event);
+}
+
+// ソケットイベントを待機する
+bool UnixWaitSockEvent(SOCK_EVENT *event, UINT timeout)
+{
+	UINT num_read, num_write;
+	UINT *reads, *writes;
+	UINT n;
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (event == NULL)
+	{
+		return false;
+	}
+
+	LockList(event->SockList);
+	{
+		UINT i;
+		num_read = LIST_NUM(event->SockList) + 1;
+		reads = ZeroMallocFast(sizeof(SOCK *) * num_read);
+
+		num_write = 0;
+
+		for (i = 0;i < (num_read - 1);i++)
+		{
+			SOCK *s = LIST_DATA(event->SockList, i);
+			reads[i] = s->socket;
+			if (s->WriteBlocked)
+			{
+				num_write++;
+			}
+		}
+
+		reads[num_read - 1] = event->pipe_read;
+
+		writes = ZeroMallocFast(sizeof(SOCK *) * num_write);
+
+		n = 0;
+
+		for (i = 0;i < (num_read - 1);i++)
+		{
+			SOCK *s = LIST_DATA(event->SockList, i);
+			if (s->WriteBlocked)
+			{
+				writes[n++] = s->socket;
+			}
+		}
+	}
+	UnlockList(event->SockList);
+
+	if (0)
+	{
+		UINT i;
+		Print("UnixSelectInner: ");
+		for (i = 0;i < num_read;i++)
+		{
+			Print("%u ", reads[i]);
+		}
+		Print("\n");
+	}
+
+	UnixSelectInner(num_read, reads, num_write, writes, timeout);
+
+	read(event->pipe_read, tmp, sizeof(tmp));
+
+	Free(reads);
+	Free(writes);
+
+	return true;
+}
+
+// ソケットイベントをセットする
+void UnixSetSockEvent(SOCK_EVENT *event)
+{
+	// 引数チェック
+	if (event == NULL)
+	{
+		return;
+	}
+
+	UnixWritePipe(event->pipe_write);
+}
+
+// ソケットの select の実行
+void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout)
+{
+	struct pollfd *p;
+	UINT num;
+	UINT i;
+	UINT n;
+	UINT num_read_total, num_write_total;
+
+	if (num_read != 0 && reads == NULL)
+	{
+		num_read = 0;
+	}
+	if (num_write != 0 && writes == NULL)
+	{
+		num_write = 0;
+	}
+
+	if (timeout == 0)
+	{
+		return;
+	}
+
+	num_read_total = num_write_total = 0;
+	for (i = 0;i < num_read;i++)
+	{
+		if (reads[i] != INVALID_SOCKET)
+		{
+			num_read_total++;
+		}
+	}
+	for (i = 0;i < num_write;i++)
+	{
+		if (writes[i] != INVALID_SOCKET)
+		{
+			num_write_total++;
+		}
+	}
+
+	num = num_read_total + num_write_total;
+	p = ZeroMallocFast(sizeof(struct pollfd) * num);
+
+	n = 0;
+
+	for (i = 0;i < num_read;i++)
+	{
+		if (reads[i] != INVALID_SOCKET)
+		{
+			struct pollfd *pfd = &p[n++];
+			pfd->fd = reads[i];
+			pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP;
+		}
+	}
+
+	for (i = 0;i < num_write;i++)
+	{
+		if (writes[i] != INVALID_SOCKET)
+		{
+			struct pollfd *pfd = &p[n++];
+			pfd->fd = writes[i];
+			pfd->events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLOUT;
+		}
+	}
+
+	if (num != 0)
+	{
+		poll(p, num, timeout == INFINITE ? -1 : (int)timeout);
+	}
+	else
+	{
+		SleepThread(timeout);
+	}
+
+	Free(p);
+}
+
+// ソケットイベントのクリーンアップ
+void UnixCleanupSockEvent(SOCK_EVENT *event)
+{
+	UINT i;
+	// 引数チェック
+	if (event == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(event->SockList);i++)
+	{
+		SOCK *s = LIST_DATA(event->SockList, i);
+
+		ReleaseSock(s);
+	}
+
+	ReleaseList(event->SockList);
+
+	UnixDeletePipe(event->pipe_read, event->pipe_write);
+
+	Free(event);
+}
+
+// ソケットイベントを作成する
+SOCK_EVENT *UnixNewSockEvent()
+{
+	SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
+
+	e->SockList = NewList(NULL);
+	e->ref = NewRef();
+
+	UnixNewPipe(&e->pipe_read, &e->pipe_write);
+
+	return e;
+}
+
+// パイプを閉じる
+void UnixDeletePipe(int p1, int p2)
+{
+	if (p1 != -1)
+	{
+		close(p1);
+	}
+
+	if (p2 != -1)
+	{
+		close(p2);
+	}
+}
+
+// パイプに書き込む
+void UnixWritePipe(int pipe_write)
+{
+	char c = 1;
+	write(pipe_write, &c, 1);
+}
+
+// 新しいパイプを作成する
+void UnixNewPipe(int *pipe_read, int *pipe_write)
+{
+	int fd[2];
+	// 引数チェック
+	if (pipe_read == NULL || pipe_write == NULL)
+	{
+		return;
+	}
+
+	fd[0] = fd[1] = 0;
+
+	pipe(fd);
+
+	*pipe_read = fd[0];
+	*pipe_write = fd[1];
+
+	UnixSetSocketNonBlockingMode(*pipe_write, true);
+	UnixSetSocketNonBlockingMode(*pipe_read, true);
+}
+
+// 非同期ソケットの解放
+void UnixFreeAsyncSocket(SOCK *sock)
+{
+	UINT p;
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return;
+	}
+
+	Lock(sock->lock);
+	{
+		if (sock->AsyncMode == false)
+		{
+			Unlock(sock->lock);
+			return;
+		}
+
+		sock->AsyncMode = false;
+
+		// このソケットが SockEvent に関連付けられているかどうか調べる
+		if (sock->SockEvent != NULL)
+		{
+			SOCK_EVENT *e = sock->SockEvent;
+
+			AddRef(e->ref);
+
+			p = e->pipe_write;
+			LockList(e->SockList);
+			{
+				if (Delete(e->SockList, sock))
+				{
+					ReleaseSock(sock);
+				}
+			}
+			UnlockList(e->SockList);
+
+			// ソケットイベントを解放する
+			ReleaseSockEvent(sock->SockEvent);
+			sock->SockEvent = NULL;
+
+			SetSockEvent(e);
+
+			ReleaseSockEvent(e);
+		}
+	}
+	Unlock(sock->lock);
+}
+
+// ソケットを非同期に設定する
+void UnixInitAsyncSocket(SOCK *sock)
+{
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return;
+	}
+	if (sock->AsyncMode)
+	{
+		// すでに非同期ソケットになっている
+		return;
+	}
+	if (sock->ListenMode != false || (sock->Type == SOCK_TCP && sock->Connected == false))
+	{
+		return;
+	}
+
+	sock->AsyncMode = true;
+
+	UnixSetSocketNonBlockingMode(sock->socket, true);
+}
+
+// ソケットライブラリの初期化
+void UnixInitSocketLibrary()
+{
+	// 特に何もしない
+}
+
+// ソケットライブラリの解放
+void UnixFreeSocketLibrary()
+{
+	// 特に何もしない
+}
+
+#endif	// OS_UNIX
+
+#ifdef	OS_WIN32		// Windows 用コード
+
+NETWORK_WIN32_FUNCTIONS *w32net;
+
+// IP_ADAPTER_INDEX_MAP の比較
+int CompareIpAdapterIndexMap(void *p1, void *p2)
+{
+	IP_ADAPTER_INDEX_MAP *a1, *a2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	a1 = *(IP_ADAPTER_INDEX_MAP **)p1;
+	a2 = *(IP_ADAPTER_INDEX_MAP **)p2;
+	if (a1 == NULL || a2 == NULL)
+	{
+		return 0;
+	}
+
+	if (a1->Index > a2->Index)
+	{
+		return 1;
+	}
+	else if (a1->Index < a2->Index)
+	{
+		return -1;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+// アダプタの IP アドレスを更新
+bool Win32RenewAddressByGuid(char *guid)
+{
+	IP_ADAPTER_INDEX_MAP a;
+	// 引数チェック
+	if (guid == NULL)
+	{
+		return false;
+	}
+
+	Zero(&a, sizeof(a));
+	if (Win32GetAdapterFromGuid(&a, guid) == false)
+	{
+		return false;
+	}
+
+	return Win32RenewAddress(&a);
+}
+bool Win32RenewAddress(void *a)
+{
+	DWORD ret;
+	// 引数チェック
+	if (a == NULL)
+	{
+		return false;
+	}
+	if (w32net->IpRenewAddress == NULL)
+	{
+		return false;
+	}
+
+	ret = w32net->IpRenewAddress(a);
+
+	if (ret == NO_ERROR)
+	{
+		return true;
+	}
+	else
+	{
+		Debug("IpRenewAddress: Error: %u\n", ret);
+		return false;
+	}
+}
+
+// アダプタの IP アドレスを解放
+bool Win32ReleaseAddress(void *a)
+{
+	DWORD ret;
+	// 引数チェック
+	if (a == NULL)
+	{
+		return false;
+	}
+	if (w32net->IpReleaseAddress == NULL)
+	{
+		return false;
+	}
+
+	ret = w32net->IpReleaseAddress(a);
+
+	if (ret == NO_ERROR)
+	{
+		return true;
+	}
+	else
+	{
+		Debug("IpReleaseAddress: Error: %u\n", ret);
+		return false;
+	}
+}
+bool Win32ReleaseAddressByGuid(char *guid)
+{
+	IP_ADAPTER_INDEX_MAP a;
+	// 引数チェック
+	if (guid == NULL)
+	{
+		return false;
+	}
+
+	Zero(&a, sizeof(a));
+	if (Win32GetAdapterFromGuid(&a, guid) == false)
+	{
+		return false;
+	}
+
+	return Win32ReleaseAddress(&a);
+}
+void Win32ReleaseAddressByGuidExThread(THREAD *t, void *param)
+{
+	WIN32_RELEASEADDRESS_THREAD_PARAM *p;
+	// 引数チェック
+	if (t == NULL || param == NULL)
+	{
+		return;
+	}
+
+	p = (WIN32_RELEASEADDRESS_THREAD_PARAM *)param;
+
+	AddRef(p->Ref);
+
+	NoticeThreadInit(t);
+
+	AddWaitThread(t);
+
+	if (p->Renew == false)
+	{
+		p->Ok = Win32ReleaseAddressByGuid(p->Guid);
+	}
+	else
+	{
+		p->Ok = Win32RenewAddressByGuid(p->Guid);
+	}
+
+	ReleaseWin32ReleaseAddressByGuidThreadParam(p);
+
+	DelWaitThread(t);
+}
+bool Win32RenewAddressByGuidEx(char *guid, UINT timeout)
+{
+	return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, true);
+}
+bool Win32ReleaseAddressByGuidEx(char *guid, UINT timeout)
+{
+	return Win32ReleaseOrRenewAddressByGuidEx(guid, timeout, false);
+}
+bool Win32ReleaseOrRenewAddressByGuidEx(char *guid, UINT timeout, bool renew)
+{
+	THREAD *t;
+	WIN32_RELEASEADDRESS_THREAD_PARAM *p;
+	bool ret = false;
+	UINT64 start_tick = 0;
+	UINT64 end_tick = 0;
+	// 引数チェック
+	if (guid == NULL)
+	{
+		return false;
+	}
+	if (timeout == 0)
+	{
+		timeout = INFINITE;
+	}
+
+	p = ZeroMalloc(sizeof(WIN32_RELEASEADDRESS_THREAD_PARAM));
+	p->Ref = NewRef();
+	StrCpy(p->Guid, sizeof(p->Guid), guid);
+	p->Timeout = timeout;
+	p->Renew = renew;
+
+	t = NewThread(Win32ReleaseAddressByGuidExThread, p);
+	WaitThreadInit(t);
+	start_tick = Tick64();
+	end_tick = start_tick + (UINT64)timeout;
+
+	while (true)
+	{
+		UINT64 now = Tick64();
+		UINT64 remain;
+		UINT remain32;
+
+		if (now >= end_tick)
+		{
+			break;
+		}
+
+		remain = end_tick - now;
+		remain32 = MIN((UINT)remain, 100);
+
+		if (WaitThread(t, remain32))
+		{
+			break;
+		}
+	}
+
+	ReleaseThread(t);
+
+	if (p->Ok)
+	{
+		ret = true;
+	}
+
+	ReleaseWin32ReleaseAddressByGuidThreadParam(p);
+
+	return ret;
+}
+void ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM *p)
+{
+	// 引数チェック
+	if (p == NULL)
+	{
+		return;
+	}
+
+	if (Release(p->Ref) == 0)
+	{
+		Free(p);
+	}
+}
+
+// アダプタを GUID から取得
+bool Win32GetAdapterFromGuid(void *a, char *guid)
+{
+	bool ret = false;
+	IP_INTERFACE_INFO *info;
+	UINT size;
+	int i;
+	LIST *o;
+	wchar_t tmp[MAX_SIZE];
+
+	// 引数チェック
+	if (a == NULL || guid == NULL)
+	{
+		return false;
+	}
+	if (w32net->GetInterfaceInfo == NULL)
+	{
+		return false;
+	}
+
+	UniFormat(tmp, sizeof(tmp), L"\\DEVICE\\TCPIP_%S", guid);
+
+	size = sizeof(IP_INTERFACE_INFO);
+	info = ZeroMallocFast(size);
+
+	if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
+	{
+		Free(info);
+		info = ZeroMallocFast(size);
+	}
+
+	if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
+	{
+		Free(info);
+		return false;
+	}
+
+	o = NewListFast(CompareIpAdapterIndexMap);
+
+	for (i = 0;i < info->NumAdapters;i++)
+	{
+		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
+
+		Add(o, a);
+	}
+
+	Sort(o);
+
+	for (i = 0;i < (int)(LIST_NUM(o));i++)
+	{
+		IP_ADAPTER_INDEX_MAP *e = LIST_DATA(o, i);
+
+		if (UniStrCmpi(e->Name, tmp) == 0)
+		{
+			Copy(a, e, sizeof(IP_ADAPTER_INDEX_MAP));
+			ret = true;
+			break;
+		}
+	}
+
+	ReleaseList(o);
+
+	Free(info);
+
+	return ret;
+}
+
+// テスト
+void Win32NetworkTest()
+{
+	IP_INTERFACE_INFO *info;
+	UINT size;
+	int i;
+	LIST *o;
+
+	size = sizeof(IP_INTERFACE_INFO);
+	info = ZeroMallocFast(size);
+
+	if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
+	{
+		Free(info);
+		info = ZeroMallocFast(size);
+	}
+
+	if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
+	{
+		Free(info);
+		return;
+	}
+
+	o = NewListFast(CompareIpAdapterIndexMap);
+
+	for (i = 0;i < info->NumAdapters;i++)
+	{
+		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
+
+		Add(o, a);
+	}
+
+	Sort(o);
+
+	for (i = 0;i < (int)(LIST_NUM(o));i++)
+	{
+		IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
+
+		DoNothing();
+	}
+
+	ReleaseList(o);
+
+	Free(info);
+}
+
+// 指定された LAN カードの DHCP アドレスを更新する
+void Win32RenewDhcp9x(UINT if_id)
+{
+	IP_INTERFACE_INFO *info;
+	UINT size;
+	int i;
+	LIST *o;
+	// 引数チェック
+	if (if_id == 0)
+	{
+		return;
+	}
+
+	size = sizeof(IP_INTERFACE_INFO);
+	info = ZeroMallocFast(size);
+
+	if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
+	{
+		Free(info);
+		info = ZeroMallocFast(size);
+	}
+
+	if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
+	{
+		Free(info);
+		return;
+	}
+
+	o = NewListFast(CompareIpAdapterIndexMap);
+
+	for (i = 0;i < info->NumAdapters;i++)
+	{
+		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
+
+		Add(o, a);
+	}
+
+	Sort(o);
+
+	for (i = 0;i < (int)(LIST_NUM(o));i++)
+	{
+		IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
+
+		if (a->Index == if_id)
+		{
+			char arg[MAX_PATH];
+			Format(arg, sizeof(arg), "/renew %u", i);
+			Run("ipconfig.exe", arg, true, false);
+		}
+	}
+
+	ReleaseList(o);
+
+	Free(info);
+}
+
+// 指定された LAN カードの DHCP アドレスを解放する
+void Win32ReleaseDhcp9x(UINT if_id, bool wait)
+{
+	IP_INTERFACE_INFO *info;
+	UINT size;
+	int i;
+	LIST *o;
+	// 引数チェック
+	if (if_id == 0)
+	{
+		return;
+	}
+
+	size = sizeof(IP_INTERFACE_INFO);
+	info = ZeroMallocFast(size);
+
+	if (w32net->GetInterfaceInfo(info, &size) == ERROR_INSUFFICIENT_BUFFER)
+	{
+		Free(info);
+		info = ZeroMallocFast(size);
+	}
+
+	if (w32net->GetInterfaceInfo(info, &size) != NO_ERROR)
+	{
+		Free(info);
+		return;
+	}
+
+	o = NewListFast(CompareIpAdapterIndexMap);
+
+	for (i = 0;i < info->NumAdapters;i++)
+	{
+		IP_ADAPTER_INDEX_MAP *a = &info->Adapter[i];
+
+		Add(o, a);
+	}
+
+	Sort(o);
+
+	for (i = 0;i < (int)(LIST_NUM(o));i++)
+	{
+		IP_ADAPTER_INDEX_MAP *a = LIST_DATA(o, i);
+
+		if (a->Index == if_id)
+		{
+			char arg[MAX_PATH];
+			Format(arg, sizeof(arg), "/release %u", i);
+			Run("ipconfig.exe", arg, true, wait);
+		}
+	}
+
+	ReleaseList(o);
+
+	Free(info);
+}
+
+// DHCP サーバーから IP アドレスを再取得する
+void Win32RenewDhcp()
+{
+	if (OS_IS_WINDOWS_NT(GetOsInfo()->OsType))
+	{
+		Run("ipconfig.exe", "/renew", true, false);
+		if (MsIsVista())
+		{
+			Run("ipconfig.exe", "/renew6", true, false);
+		}
+		else
+		{
+			Run("netsh.exe", "int ipv6 renew", true, false);
+		}
+	}
+	else
+	{
+		Run("ipconfig.exe", "/renew_all", true, false);
+	}
+}
+
+// 指定された文字列を含む仮想 LAN カードの一覧を列挙する
+char **Win32EnumVLan(char *tag_name)
+{
+	MIB_IFTABLE *p;
+	UINT ret;
+	UINT size_needed;
+	UINT num_retry = 0;
+	UINT i;
+	LIST *o;
+	char **ss;
+	// 引数チェック
+	if (tag_name == 0)
+	{
+		return NULL;
+	}
+
+RETRY:
+	p = ZeroMallocFast(sizeof(MIB_IFTABLE));
+	size_needed = 0;
+
+	// 必要なサイズを調べる
+	ret = w32net->GetIfTable(p, &size_needed, 0);
+	if (ret == ERROR_INSUFFICIENT_BUFFER)
+	{
+		// 必要なサイズ分のメモリブロックを再確保
+		Free(p);
+		p = ZeroMallocFast(size_needed);
+	}
+	else if (ret != NO_ERROR)
+	{
+		// 取得失敗
+FAILED:
+		Free(p);
+		return NULL;
+	}
+
+	// 実際に取得する
+	ret = w32net->GetIfTable(p, &size_needed, FALSE);
+	if (ret != NO_ERROR)
+	{
+		// 取得失敗
+		if ((++num_retry) >= 5)
+		{
+			goto FAILED;
+		}
+		Free(p);
+		goto RETRY;
+	}
+
+	// 検索
+	ret = 0;
+	o = NewListFast(CompareStr);
+	for (i = 0;i < p->dwNumEntries;i++)
+	{
+		MIB_IFROW *r = &p->table[i];
+		if (SearchStrEx(r->bDescr, tag_name, 0, false) != INFINITE)
+		{
+			char *s = CopyStr(r->bDescr);
+			Add(o, s);
+		}
+	}
+
+	Free(p);
+
+	// ソート
+	Sort(o);
+
+	// 文字列に変換
+	ss = ZeroMallocFast(sizeof(char *) * (LIST_NUM(o) + 1));
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		ss[i] = LIST_DATA(o, i);
+	}
+	ss[LIST_NUM(o)] = NULL;
+
+	ReleaseList(o);
+
+	return ss;
+}
+
+// 仮想 LAN カードのインスタンス名から仮想 LAN カードの ID を取得する
+UINT Win32GetVLanInterfaceID(char *instance_name)
+{
+	MIB_IFTABLE *p;
+	UINT ret;
+	UINT size_needed;
+	UINT num_retry = 0;
+	UINT i;
+	char ps_miniport_str[MAX_SIZE];
+	char ps_miniport_str2[MAX_SIZE];
+	// 引数チェック
+	if (instance_name == 0)
+	{
+		return 0;
+	}
+
+RETRY:
+	p = ZeroMallocFast(sizeof(MIB_IFTABLE));
+	size_needed = 0;
+
+	// 必要なサイズを調べる
+	ret = w32net->GetIfTable(p, &size_needed, 0);
+	if (ret == ERROR_INSUFFICIENT_BUFFER)
+	{
+		// 必要なサイズ分のメモリブロックを再確保
+		Free(p);
+		p = ZeroMallocFast(size_needed);
+	}
+	else if (ret != NO_ERROR)
+	{
+		// 取得失敗
+FAILED:
+		Free(p);
+		Debug("******** GetIfTable Failed 1. Err = %u\n", ret);
+		return 0;
+	}
+
+	// 実際に取得する
+	ret = w32net->GetIfTable(p, &size_needed, FALSE);
+	if (ret != NO_ERROR)
+	{
+		// 取得失敗
+		if ((++num_retry) >= 5)
+		{
+			goto FAILED;
+		}
+		Free(p);
+		Debug("******** GetIfTable Failed 2. Err = %u\n", ret);
+		goto RETRY;
+	}
+
+	// "%s - パケット スケジューラ ミニポート"
+	Format(ps_miniport_str, sizeof(ps_miniport_str), "%s - ", instance_name);
+	Format(ps_miniport_str2, sizeof(ps_miniport_str2), "%s (Microsoft", instance_name);
+
+	// 検索
+	ret = 0;
+	for (i = 0;i < p->dwNumEntries;i++)
+	{
+		MIB_IFROW *r = &p->table[i];
+		if (instance_name[0] != '@')
+		{
+			if (StrCmpi(r->bDescr, instance_name) == 0 || StartWith(r->bDescr, ps_miniport_str) || StartWith(r->bDescr, ps_miniport_str2))
+			{
+				ret = r->dwIndex;
+			}
+		}
+		else
+		{
+			if (SearchStrEx(r->bDescr, &instance_name[1], 0, false) != INFINITE)
+			{
+				ret = r->dwIndex;
+			}
+		}
+
+		Debug("if[%u] (0x%x): %s\n", i, r->dwIndex, r->bDescr);
+	}
+
+	Free(p);
+
+	return ret;
+}
+
+// デフォルトの DNS サーバーアドレスを取得する
+bool Win32GetDefaultDns(IP *ip, char *domain, UINT size)
+{
+	FIXED_INFO *info;
+	UINT info_size;
+	char *dns_name;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return false;
+	}
+	Zero(ip, sizeof(IP));
+	info_size = 0;
+	info = ZeroMallocFast(sizeof(FIXED_INFO));
+	if (w32net->GetNetworkParams(info, &info_size) == ERROR_BUFFER_OVERFLOW)
+	{
+		Free(info);
+		info = ZeroMallocFast(info_size);
+	}
+	if (w32net->GetNetworkParams(info, &info_size) != NO_ERROR)
+	{
+		Free(info);
+		return false;
+	}
+
+	if (info->DnsServerList.IpAddress.String == NULL)
+	{
+		Free(info);
+		return false;
+	}
+
+	dns_name = info->DnsServerList.IpAddress.String;
+	StrToIP(ip, dns_name);
+
+	if (domain != NULL)
+	{
+		StrCpy(domain, size, info->DomainName);
+		Trim(domain);
+	}
+
+	Free(info);
+
+	return true;
+}
+
+// Win32 用 IP 変換関数
+void Win32UINTToIP(IP *ip, UINT i)
+{
+	UINTToIP(ip, i);
+}
+
+// Win32 用 IP 変換関数
+UINT Win32IPToUINT(IP *ip)
+{
+	return IPToUINT(ip);
+}
+
+// ルーティングテーブルからルーティングエントリを削除
+void Win32DeleteRouteEntry(ROUTE_ENTRY *e)
+{
+	MIB_IPFORWARDROW *p;
+	// 引数チェック
+	if (e == NULL)
+	{
+		return;
+	}
+
+	p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
+	Win32RouteEntryToIpForwardRow(p, e);
+
+	// 削除
+	w32net->DeleteIpForwardEntry(p);
+
+	Free(p);
+}
+
+// ルーティングテーブルにルーティングエントリを追加
+bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists)
+{
+	bool ret = false;
+	bool dummy = false;
+	MIB_IPFORWARDROW *p;
+	UINT err = 0;
+	// 引数チェック
+	if (e == NULL)
+	{
+		return false;
+	}
+	if (already_exists == NULL)
+	{
+		already_exists = &dummy;
+	}
+
+	*already_exists = false;
+
+	p = ZeroMallocFast(sizeof(MIB_IPFORWARDROW));
+	Win32RouteEntryToIpForwardRow(p, e);
+
+	// 追加
+	err = w32net->CreateIpForwardEntry(p);
+	if (err != 0)
+	{
+		if (err == ERROR_OBJECT_ALREADY_EXISTS)
+		{
+			Debug("CreateIpForwardEntry: Already Exists\n");
+			*already_exists = true;
+			ret = true;
+		}
+		else
+		{
+			Debug("CreateIpForwardEntry Error: %u\n", err);
+			ret = false;
+		}
+	}
+	else
+	{
+		ret = true;
+	}
+
+	Free(p);
+
+	return ret;
+}
+
+// ルーティングテーブルの取得
+ROUTE_TABLE *Win32GetRouteTable()
+{
+	ROUTE_TABLE *t = ZeroMallocFast(sizeof(ROUTE_TABLE));
+	MIB_IPFORWARDTABLE *p;
+	UINT ret;
+	UINT size_needed;
+	UINT num_retry = 0;
+	LIST *o;
+	UINT i;
+	ROUTE_ENTRY *e;
+
+RETRY:
+	p = ZeroMallocFast(sizeof(MIB_IFTABLE));
+	size_needed = 0;
+
+	// 必要なサイズを調べる
+	ret = w32net->GetIpForwardTable(p, &size_needed, 0);
+	if (ret == ERROR_INSUFFICIENT_BUFFER)
+	{
+		// 必要なサイズ分のメモリブロックを再確保
+		Free(p);
+		p = ZeroMallocFast(size_needed);
+	}
+	else if (ret != NO_ERROR)
+	{
+		// 取得失敗
+FAILED:
+		Free(p);
+		t->Entry = MallocFast(0);
+		return t;
+	}
+
+	// 実際に取得する
+	ret = w32net->GetIpForwardTable(p, &size_needed, FALSE);
+	if (ret != NO_ERROR)
+	{
+		// 取得失敗
+		if ((++num_retry) >= 5)
+		{
+			goto FAILED;
+		}
+		Free(p);
+		goto RETRY;
+	}
+
+	// リストに追加していく
+	o = NewListFast(Win32CompareRouteEntryByMetric);
+	for (i = 0;i < p->dwNumEntries;i++)
+	{
+		e = ZeroMallocFast(sizeof(ROUTE_ENTRY));
+		Win32IpForwardRowToRouteEntry(e, &p->table[i]);
+		Add(o, e);
+	}
+	Free(p);
+
+	// メトリック順にソート
+	Sort(o);
+
+	// 結果を結合
+	t->NumEntry = LIST_NUM(o);
+	t->Entry = ToArrayEx(o, true);
+	ReleaseList(o);
+
+	return t;
+}
+
+// ルーティングエントリをメトリックによってソートする
+int Win32CompareRouteEntryByMetric(void *p1, void *p2)
+{
+	ROUTE_ENTRY *e1, *e2;
+	// 引数チェック
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+
+	e1 = *(ROUTE_ENTRY **)p1;
+	e2 = *(ROUTE_ENTRY **)p2;
+	if (e1 == NULL || e2 == NULL)
+	{
+		return 0;
+	}
+
+	if (e1->Metric > e2->Metric)
+	{
+		return 1;
+	}
+	else if (e1->Metric == e2->Metric)
+	{
+		return 0;
+	}
+	else
+	{
+		return -1;
+	}
+}
+
+// ROUTE_ENTRY を MIB_IPFORWARDROW に変換
+void Win32RouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry)
+{
+	MIB_IPFORWARDROW *r;
+	// 引数チェック
+	if (entry == NULL || ip_forward_row == NULL)
+	{
+		return;
+	}
+
+	r = (MIB_IPFORWARDROW *)ip_forward_row;
+	Zero(r, sizeof(MIB_IPFORWARDROW));
+
+	// IP アドレス
+	r->dwForwardDest = Win32IPToUINT(&entry->DestIP);
+	// サブネットマスク
+	r->dwForwardMask = Win32IPToUINT(&entry->DestMask);
+	// ゲートウェイ IP アドレス
+	r->dwForwardNextHop = Win32IPToUINT(&entry->GatewayIP);
+	// ローカルルーティングフラグ
+	if (entry->LocalRouting)
+	{
+		// ローカル
+		r->dwForwardType = 3;
+	}
+	else
+	{
+		// リモートルータ
+		r->dwForwardType = 4;
+	}
+	// プロトコル
+	r->dwForwardProto = r->dwForwardType - 1;	// 大抵の場合 1 引けば良い
+	if (entry->PPPConnection)
+	{
+		// PPP ちゃうかな？ 危険！
+		r->dwForwardProto++;
+	}
+	// メトリック
+	r->dwForwardMetric1 = entry->Metric;
+
+	if (MsIsVista() == false)
+	{
+		r->dwForwardMetric2 = r->dwForwardMetric3 = r->dwForwardMetric4 = r->dwForwardMetric5 = INFINITE;
+	}
+	else
+	{
+		r->dwForwardMetric2 = r->dwForwardMetric3 = r->dwForwardMetric4 = r->dwForwardMetric5 = 0;
+		r->dwForwardAge = 163240;
+	}
+
+	// インターフェイス ID
+	r->dwForwardIfIndex = entry->InterfaceID;
+
+	Debug("Win32RouteEntryToIpForwardRow()\n");
+	Debug(" r->dwForwardDest=%X\n", r->dwForwardDest);
+	Debug(" r->dwForwardMask=%X\n", r->dwForwardMask);
+	Debug(" r->dwForwardNextHop=%X\n", r->dwForwardNextHop);
+	Debug(" r->dwForwardType=%u\n", r->dwForwardType);
+	Debug(" r->dwForwardProto=%u\n", r->dwForwardProto);
+	Debug(" r->dwForwardMetric1=%u\n", r->dwForwardMetric1);
+	Debug(" r->dwForwardMetric2=%u\n", r->dwForwardMetric2);
+	Debug(" r->dwForwardIfIndex=%u\n", r->dwForwardIfIndex);
+}
+
+// MIB_IPFORWARDROW を ROUTE_ENTRY に変換
+void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row)
+{
+	MIB_IPFORWARDROW *r;
+	// 引数チェック
+	if (entry == NULL || ip_forward_row == NULL)
+	{
+		return;
+	}
+
+	r = (MIB_IPFORWARDROW *)ip_forward_row;
+
+	Zero(entry, sizeof(ROUTE_ENTRY));
+	// IP アドレス
+	Win32UINTToIP(&entry->DestIP, r->dwForwardDest);
+	// サブネットマスク
+	Win32UINTToIP(&entry->DestMask, r->dwForwardMask);
+	// ゲートウェイ IP アドレス
+	Win32UINTToIP(&entry->GatewayIP, r->dwForwardNextHop);
+	// ローカルルーティングフラグ
+	if (r->dwForwardType == 3)
+	{
+		entry->LocalRouting = true;
+	}
+	else
+	{
+		entry->LocalRouting = false;
+	}
+	if (entry->LocalRouting && r->dwForwardProto == 3)
+	{
+		// PPP。危険！
+		entry->PPPConnection = true;
+	}
+	// メトリック
+	entry->Metric = r->dwForwardMetric1;
+	// インターフェイス ID
+	entry->InterfaceID = r->dwForwardIfIndex;
+}
+
+// ソケットライブラリの初期化
+void Win32InitSocketLibrary()
+{
+	WSADATA data;
+	Zero(&data, sizeof(data));
+	WSAStartup(MAKEWORD(2, 2), &data);
+
+	// DLL 関数の読み込み
+	w32net = ZeroMalloc(sizeof(NETWORK_WIN32_FUNCTIONS));
+	w32net->hIpHlpApi32 = LoadLibrary("iphlpapi.dll");
+
+	if (w32net->hIpHlpApi32 != NULL)
+	{
+		w32net->CreateIpForwardEntry =
+			(DWORD (__stdcall *)(PMIB_IPFORWARDROW))
+			GetProcAddress(w32net->hIpHlpApi32, "CreateIpForwardEntry");
+
+		w32net->DeleteIpForwardEntry =
+			(DWORD (__stdcall *)(PMIB_IPFORWARDROW))
+			GetProcAddress(w32net->hIpHlpApi32, "DeleteIpForwardEntry");
+
+		w32net->GetIfTable =
+			(DWORD (__stdcall *)(PMIB_IFTABLE, PULONG, BOOL))
+			GetProcAddress(w32net->hIpHlpApi32, "GetIfTable");
+
+		w32net->GetIpForwardTable =
+			(DWORD (__stdcall *)(PMIB_IPFORWARDTABLE, PULONG, BOOL))
+			GetProcAddress(w32net->hIpHlpApi32, "GetIpForwardTable");
+
+		w32net->GetNetworkParams =
+			(DWORD (__stdcall *)(PFIXED_INFO,PULONG))
+			GetProcAddress(w32net->hIpHlpApi32, "GetNetworkParams");
+
+		w32net->IpRenewAddress =
+			(DWORD (__stdcall *)(PIP_ADAPTER_INDEX_MAP))
+			GetProcAddress(w32net->hIpHlpApi32, "IpRenewAddress");
+
+		w32net->IpReleaseAddress =
+			(DWORD (__stdcall *)(PIP_ADAPTER_INDEX_MAP))
+			GetProcAddress(w32net->hIpHlpApi32, "IpReleaseAddress");
+
+		w32net->GetInterfaceInfo =
+			(DWORD (__stdcall *)(PIP_INTERFACE_INFO, PULONG))
+			GetProcAddress(w32net->hIpHlpApi32, "GetInterfaceInfo");
+
+		w32net->GetAdaptersInfo =
+			(DWORD (__stdcall *)(PIP_ADAPTER_INFO, PULONG))
+			GetProcAddress(w32net->hIpHlpApi32, "GetAdaptersInfo");
+
+		w32net->GetExtendedTcpTable =
+			(DWORD (__stdcall *)(PVOID,PDWORD,BOOL,ULONG,_TCP_TABLE_CLASS,ULONG))
+			GetProcAddress(w32net->hIpHlpApi32, "GetExtendedTcpTable");
+
+		w32net->AllocateAndGetTcpExTableFromStack =
+			(DWORD (__stdcall *)(PVOID *,BOOL,HANDLE,DWORD,DWORD))
+			GetProcAddress(w32net->hIpHlpApi32, "AllocateAndGetTcpExTableFromStack");
+
+		w32net->GetTcpTable =
+			(DWORD (__stdcall *)(PMIB_TCPTABLE,PDWORD,BOOL))
+			GetProcAddress(w32net->hIpHlpApi32, "GetTcpTable");
+
+		w32net->NotifyRouteChange =
+			(DWORD (__stdcall *)(PHANDLE,LPOVERLAPPED))
+			GetProcAddress(w32net->hIpHlpApi32, "NotifyRouteChange");
+
+		w32net->CancelIPChangeNotify =
+			(BOOL (__stdcall *)(LPOVERLAPPED))
+			GetProcAddress(w32net->hIpHlpApi32, "CancelIPChangeNotify");
+
+		w32net->NhpAllocateAndGetInterfaceInfoFromStack =
+			(DWORD (__stdcall *)(IP_INTERFACE_NAME_INFO **,PDWORD,BOOL,HANDLE,DWORD))
+			GetProcAddress(w32net->hIpHlpApi32, "NhpAllocateAndGetInterfaceInfoFromStack");
+	}
+}
+
+// ソケットライブラリの解放
+void Win32FreeSocketLibrary()
+{
+	if (w32net != NULL)
+	{
+		FreeLibrary(w32net->hIpHlpApi32);
+
+		Free(w32net);
+		w32net = NULL;
+	}
+
+	WSACleanup();
+}
+
+// キャンセル
+void Win32Cancel(CANCEL *c)
+{
+	// 引数チェック
+	if (c == NULL)
+	{
+		return;
+	}
+
+	SetEvent((HANDLE)c->hEvent);
+}
+
+// キャンセルのクリーンアップ
+void Win32CleanupCancel(CANCEL *c)
+{
+	// 引数チェック
+	if (c == NULL)
+	{
+		return;
+	}
+
+	if (c->SpecialFlag == false)
+	{
+		CloseHandle(c->hEvent);
+	}
+
+	Free(c);
+}
+
+// 新しいキャンセルオブジェクト
+CANCEL *Win32NewCancel()
+{
+	CANCEL *c = ZeroMallocFast(sizeof(CANCEL));
+	c->ref = NewRef();
+	c->SpecialFlag = false;
+	c->hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+	return c;
+}
+
+// ソケットイベントの待機
+bool Win32WaitSockEvent(SOCK_EVENT *event, UINT timeout)
+{
+	// 引数チェック
+	if (event == NULL || timeout == 0)
+	{
+		return false;
+	}
+
+	if (WaitForSingleObject((HANDLE)event->hEvent, timeout) == WAIT_OBJECT_0)
+	{
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+// ソケットイベントのクリーンアップ
+void Win32CleanupSockEvent(SOCK_EVENT *event)
+{
+	// 引数チェック
+	if (event == NULL)
+	{
+		return;
+	}
+
+	CloseHandle((HANDLE)event->hEvent);
+
+	Free(event);
+}
+
+// ソケットイベントのセット
+void Win32SetSockEvent(SOCK_EVENT *event)
+{
+	// 引数チェック
+	if (event == NULL)
+	{
+		return;
+	}
+
+	SetEvent((HANDLE)event->hEvent);
+}
+
+// ソケットイベントの作成
+SOCK_EVENT *Win32NewSockEvent()
+{
+	SOCK_EVENT *e = ZeroMallocFast(sizeof(SOCK_EVENT));
+
+	e->ref = NewRef();
+	e->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
+
+	return e;
+}
+
+// ソケットをソケットイベントに関連付けして非同期に設定する
+void Win32JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
+{
+	HANDLE hEvent;
+	// 引数チェック
+	if (sock == NULL || event == NULL || sock->AsyncMode)
+	{
+		return;
+	}
+	if (sock->ListenMode != false || (sock->Type != SOCK_UDP && sock->Connected == false))
+	{
+		return;
+	}
+
+	sock->AsyncMode = true;
+
+	hEvent = event->hEvent;
+
+	// 関連付け
+	WSAEventSelect(sock->socket, hEvent, FD_READ | FD_WRITE | FD_CLOSE);
+
+	// SOCK_EVENT の参照カウンタを増加
+	AddRef(event->ref);
+	sock->SockEvent = event;
+}
+
+// ソケットを非同期に設定する
+void Win32InitAsyncSocket(SOCK *sock)
+{
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return;
+	}
+	if (sock->AsyncMode)
+	{
+		// すでに非同期ソケットになっている
+		return;
+	}
+	if (sock->ListenMode != false || (sock->Type == SOCK_TCP && sock->Connected == false))
+	{
+		return;
+	}
+
+	sock->AsyncMode = true;
+
+	// イベントの作成
+	sock->hEvent = (void *)CreateEvent(NULL, FALSE, FALSE, NULL);
+
+	// 関連付け
+	WSAEventSelect(sock->socket, sock->hEvent, FD_READ | FD_WRITE | FD_CLOSE);
+}
+
+// 非同期ソケットを解放
+void Win32FreeAsyncSocket(SOCK *sock)
+{
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return;
+	}
+
+	// 非同期ソケット
+	if (sock->hEvent != NULL)
+	{
+		CloseHandle((HANDLE)sock->hEvent);
+	}
+	sock->hEvent = NULL;
+	sock->AsyncMode = false;
+
+	// ソケットイベント
+	if (sock->SockEvent != NULL)
+	{
+		ReleaseSockEvent(sock->SockEvent);
+		sock->SockEvent = NULL;
+	}
+}
+
+// Win32 版 Select 関数
+void Win32Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
+{
+	HANDLE array[MAXIMUM_WAIT_OBJECTS];
+	UINT n, i;
+	SOCK *s;
+	// 引数チェック
+	if (timeout == 0)
+	{
+		return;
+	}
+
+	// 配列の初期化
+	Zero(array, sizeof(array));
+	n = 0;
+
+	// イベント配列の設定
+	if (set != NULL)
+	{
+		for (i = 0;i < set->NumSocket;i++)
+		{
+			s = set->Sock[i];
+			if (s != NULL)
+			{
+				Win32InitAsyncSocket(s);
+				if (s->hEvent != NULL)
+				{
+					array[n++] = (HANDLE)s->hEvent;
+				}
+			}
+		}
+	}
+	if (c1 != NULL && c1->hEvent != NULL)
+	{
+		array[n++] = c1->hEvent;
+	}
+	if (c2 != NULL && c2->hEvent != NULL)
+	{
+		array[n++] = c2->hEvent;
+	}
+
+	if (n == 0)
+	{
+		// 待つイベントが 1 つも登録されていない場合は
+		// 通常の待ち関数を呼ぶ
+		SleepThread(timeout);
+	}
+	else
+	{
+		// イベントが 1 つ以上登録されている場合はイベントを待つ
+		if (n == 1)
+		{
+			// イベントが 1 つの場合は軽量版を呼び出す
+			WaitForSingleObject(array[0], timeout);
+		}
+		else
+		{
+			// イベントが複数の場合
+			WaitForMultipleObjects(n, array, false, timeout);
+		}
+	}
+}
+
+#endif	// OS_WIN32
+
+// IPv6 がサポートされているかどうか調べる
+bool IsIPv6Supported()
+{
+#ifdef	NO_IPV6
+	return false;
+#else	// NO_IPV6
+	SOCKET s;
+
+	s = socket(AF_INET6, SOCK_STREAM, 0);
+	if (s == INVALID_SOCKET)
+	{
+		return false;
+	}
+
+	closesocket(s);
+
+	return true;
+#endif	// NO_IPV6
+}
+
+// ホストキャッシュからホスト名の取得
+bool GetHostCache(char *hostname, UINT size, IP *ip)
+{
+	bool ret;
+	// 引数チェック
+	if (hostname == NULL || ip == NULL)
+	{
+		return false;
+	}
+
+	ret = false;
+
+	LockList(HostCacheList);
+	{
+		HOSTCACHE t, *c;
+		Zero(&t, sizeof(t));
+		Copy(&t.IpAddress, ip, sizeof(IP));
+
+		c = Search(HostCacheList, &t);
+		if (c != NULL)
+		{
+			if (IsEmptyStr(c->HostName) == false)
+			{
+				ret = true;
+				StrCpy(hostname, size, c->HostName);
+			}
+			else
+			{
+				ret = true;
+				StrCpy(hostname, size, "");
+			}
+		}
+	}
+	UnlockList(HostCacheList);
+
+	return ret;
+}
+
+// ホスト名キャッシュへ追加
+void AddHostCache(IP *ip, char *hostname)
+{
+	// 引数チェック
+	if (ip == NULL || hostname == NULL)
+	{
+		return;
+	}
+	if (IsNetworkNameCacheEnabled() == false)
+	{
+		return;
+	}
+
+	LockList(HostCacheList);
+	{
+		HOSTCACHE t, *c;
+		UINT i;
+		LIST *o;
+
+		Zero(&t, sizeof(t));
+		Copy(&t.IpAddress, ip, sizeof(IP));
+
+		c = Search(HostCacheList, &t);
+		if (c == NULL)
+		{
+			c = ZeroMalloc(sizeof(HOSTCACHE));
+			Copy(&c->IpAddress, ip, sizeof(IP));
+			Add(HostCacheList, c);
+		}
+
+		StrCpy(c->HostName, sizeof(c->HostName), hostname);
+		c->Expires = Tick64() + (UINT64)EXPIRES_HOSTNAME;
+
+		o = NewListFast(NULL);
+
+		for (i = 0;i < LIST_NUM(HostCacheList);i++)
+		{
+			HOSTCACHE *c = LIST_DATA(HostCacheList, i);
+
+			if (c->Expires <= Tick64())
+			{
+				Add(o, c);
+			}
+		}
+
+		for (i = 0;i < LIST_NUM(o);i++)
+		{
+			HOSTCACHE *c = LIST_DATA(o, i);
+
+			if (Delete(HostCacheList, c))
+			{
+				Free(c);
+			}
+		}
+
+		ReleaseList(o);
+	}
+	UnlockList(HostCacheList);
+}
+
+// ホスト名キャッシュの比較
+int CompareHostCache(void *p1, void *p2)
+{
+	HOSTCACHE *c1, *c2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	c1 = *(HOSTCACHE **)p1;
+	c2 = *(HOSTCACHE **)p2;
+	if (c1 == NULL || c2 == NULL)
+	{
+		return 0;
+	}
+
+	return CmpIpAddr(&c1->IpAddress, &c2->IpAddress);
+}
+
+// ホスト名キャッシュの解放
+void FreeHostCache()
+{
+	UINT i;
+
+	for (i = 0;i < LIST_NUM(HostCacheList);i++)
+	{
+		HOSTCACHE *c = LIST_DATA(HostCacheList, i);
+
+		Free(c);
+	}
+
+	ReleaseList(HostCacheList);
+	HostCacheList = NULL;
+}
+
+// ホスト名キャッシュの初期化
+void InitHostCache()
+{
+	HostCacheList = NewList(CompareHostCache);
+}
+
+// スレッドをスレッド待機リストに追加する
+void AddWaitThread(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	AddRef(t->ref);
+
+	LockList(WaitThreadList);
+	{
+		Add(WaitThreadList, t);
+	}
+	UnlockList(WaitThreadList);
+}
+
+// スレッドを待機リストから削除する
+void DelWaitThread(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	LockList(WaitThreadList);
+	{
+		if (Delete(WaitThreadList, t))
+		{
+			ReleaseThread(t);
+		}
+	}
+	UnlockList(WaitThreadList);
+}
+
+// スレッド待機リストの作成
+void InitWaitThread()
+{
+	WaitThreadList = NewList(NULL);
+}
+
+// スレッド待機リストの解放
+void FreeWaitThread()
+{
+	UINT i, num;
+	THREAD **threads;
+
+	LockList(WaitThreadList);
+	{
+		num = LIST_NUM(WaitThreadList);
+		threads = ToArray(WaitThreadList);
+		DeleteAll(WaitThreadList);
+	}
+	UnlockList(WaitThreadList);
+
+	for (i = 0;i < num;i++)
+	{
+		THREAD *t = threads[i];
+		WaitThread(t, INFINITE);
+		ReleaseThread(t);
+	}
+
+	Free(threads);
+
+	ReleaseList(WaitThreadList);
+	WaitThreadList = NULL;
+}
+
+// 暗号リスト名をチェックする
+bool CheckCipherListName(char *name)
+{
+	UINT i;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;i < cipher_list_token->NumTokens;i++)
+	{
+		if (StrCmpi(cipher_list_token->Token[i], name) == 0)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// DHCP サーバーの IP アドレス更新
+void RenewDhcp()
+{
+#ifdef	OS_WIN32
+	Win32RenewDhcp();
+#else
+	UnixRenewDhcp();
+#endif
+}
+
+// UNIX 用ドメイン名を取得
+bool UnixGetDomainName(char *name, UINT size)
+{
+	bool ret = false;
+	BUF *b = ReadDump("/etc/resolv.conf");
+
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	while (true)
+	{
+		char *s = CfgReadNextLine(b);
+		TOKEN_LIST *t;
+
+		if (s == NULL)
+		{
+			break;
+		}
+
+		Trim(s);
+
+		t = ParseToken(s, " \t");
+		if (t != NULL)
+		{
+			if (t->NumTokens == 2)
+			{
+				if (StrCmpi(t->Token[0], "domain") == 0)
+				{
+					StrCpy(name, size, t->Token[1]);
+					ret = true;
+				}
+			}
+			FreeToken(t);
+		}
+
+		Free(s);
+	}
+
+	FreeBuf(b);
+
+	return ret;
+}
+
+// ドメイン名を取得
+bool GetDomainName(char *name, UINT size)
+{
+	bool ret = false;
+	IP ip;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+#ifdef	OS_WIN32
+	ret = Win32GetDefaultDns(&ip, name, size);
+#else	// OS_WIN32
+	ret = UnixGetDomainName(name, size);
+#endif	// OS_WIN32
+
+	return ret;
+}
+
+// デフォルトの DNS サーバーの取得
+bool GetDefaultDns(IP *ip)
+{
+	bool ret = false;
+#ifdef	OS_WIN32
+	ret = Win32GetDefaultDns(ip, NULL, 0);
+#else
+	ret = UnixGetDefaultDns(ip);
+#endif	// OS_WIN32
+	return ret;
+}
+
+// ソケットイベントの作成
+SOCK_EVENT *NewSockEvent()
+{
+	SOCK_EVENT *e = NULL;
+#ifdef	OS_WIN32
+	e = Win32NewSockEvent();
+#else
+	e = UnixNewSockEvent();
+#endif	// OS_WIN32
+	return e;
+}
+
+// ソケットイベントのセット
+void SetSockEvent(SOCK_EVENT *event)
+{
+#ifdef	OS_WIN32
+	Win32SetSockEvent(event);
+#else
+	UnixSetSockEvent(event);
+#endif	// OS_WIN32
+}
+
+// ソケットイベントのクリーンアップ
+void CleanupSockEvent(SOCK_EVENT *event)
+{
+#ifdef	OS_WIN32
+	Win32CleanupSockEvent(event);
+#else
+	UnixCleanupSockEvent(event);
+#endif	// OS_WIN32
+}
+
+// ソケットイベントの待機
+bool WaitSockEvent(SOCK_EVENT *event, UINT timeout)
+{
+	bool ret = false;
+#ifdef	OS_WIN32
+	ret = Win32WaitSockEvent(event, timeout);
+#else
+	ret = UnixWaitSockEvent(event, timeout);
+#endif	// OS_WIN32
+	return ret;
+}
+
+// ソケットイベントの解放
+void ReleaseSockEvent(SOCK_EVENT *event)
+{
+	// 引数チェック
+	if (event == NULL)
+	{
+		return;
+	}
+
+	if (Release(event->ref) == 0)
+	{
+		CleanupSockEvent(event);
+	}
+}
+
+// ソケットをソケットイベントに所属させる
+void JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event)
+{
+#ifdef	OS_WIN32
+	Win32JoinSockToSockEvent(sock, event);
+#else
+	UnixJoinSockToSockEvent(sock, event);
+#endif	// OS_WIN32
+}
+
+// 新しい特殊キャンセルオブジェクト
+CANCEL *NewCancelSpecial(void *hEvent)
+{
+	CANCEL *c;
+	// 引数チェック
+	if (hEvent == NULL)
+	{
+		return NULL;
+	}
+
+	c = ZeroMalloc(sizeof(CANCEL));
+	c->ref = NewRef();
+	c->SpecialFlag = true;
+
+#ifdef	OS_WIN32
+	c->hEvent = (HANDLE)hEvent;
+#else	// OS_WIN32
+	c->pipe_read = (int)hEvent;
+	c->pipe_write = -1;
+#endif	// OS_WIN32
+
+	return c;
+}
+
+// キャンセルオブジェクトの作成
+CANCEL *NewCancel()
+{
+	CANCEL *c = NULL;
+#ifdef	OS_WIN32
+	c = Win32NewCancel();
+#else
+	c = UnixNewCancel();
+#endif	// OS_WIN32
+	return c;
+}
+
+// キャンセルオブジェクトの解放
+void ReleaseCancel(CANCEL *c)
+{
+	// 引数チェック
+	if (c == NULL)
+	{
+		return;
+	}
+
+	if (Release(c->ref) == 0)
+	{
+		CleanupCancel(c);
+	}
+}
+
+// キャンセルオブジェクトのクリーンアップ
+void CleanupCancel(CANCEL *c)
+{
+#ifdef	OS_WIN32
+	Win32CleanupCancel(c);
+#else
+	UnixCleanupCancel(c);
+#endif
+}
+
+// キャンセル発動
+void Cancel(CANCEL *c)
+{
+#ifdef	OS_WIN32
+	Win32Cancel(c);
+#else
+	UnixCancel(c);
+#endif
+}
+
+// 指定されたルーティングテーブルから最適なルートを計算する
+ROUTE_ENTRY *GetBestRouteEntryFromRouteTable(ROUTE_TABLE *table, IP *ip)
+{
+	return GetBestRouteEntryFromRouteTableEx(table, ip, 0);
+}
+ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT exclude_if_id)
+{
+	UINT i;
+	UINT max_mask = 0;
+	UINT min_metric = INFINITE;
+	ROUTE_ENTRY *ret = NULL;
+	ROUTE_ENTRY *tmp = NULL;
+	// 引数チェック
+	if (ip == NULL || table == NULL)
+	{
+		return NULL;
+	}
+
+	if (IsIP6(ip))
+	{
+		// IPv6 は非サポート
+		return NULL;
+	}
+
+	// 対象となるルーティングテーブルのうち、
+	//  第一条件: サブネットマスクが最も大きい
+	//  第二条件: メトリック値が最も小さい
+	// ものを選択する
+	for (i = 0;i < table->NumEntry;i++)
+	{
+		ROUTE_ENTRY *e = table->Entry[i];
+		UINT dest, net, mask;
+
+		dest = IPToUINT(ip);
+		net = IPToUINT(&e->DestIP);
+		mask = IPToUINT(&e->DestMask);
+
+		if (exclude_if_id != 0)
+		{
+			if (e->InterfaceID == exclude_if_id)
+			{
+				continue;
+			}
+		}
+
+		// マスクテスト
+		if ((dest & mask) == (net & mask))
+		{
+			// これはルーティングの対象となり得る
+			if (mask >= max_mask)
+			{
+				max_mask = mask;
+				if (min_metric >= e->Metric)
+				{
+					min_metric = e->Metric;
+					tmp = e;
+				}
+			}
+		}
+	}
+
+	if (tmp != NULL)
+	{
+		UINT dest, gateway, mask;
+
+		// エントリを生成
+		ret = ZeroMallocFast(sizeof(ROUTE_ENTRY));
+
+		Copy(&ret->DestIP, ip, sizeof(IP));
+		ret->DestMask.addr[0] = 255;
+		ret->DestMask.addr[1] = 255;
+		ret->DestMask.addr[2] = 255;
+		ret->DestMask.addr[3] = 255;
+		Copy(&ret->GatewayIP, &tmp->GatewayIP, sizeof(IP));
+		ret->InterfaceID = tmp->InterfaceID;
+		ret->LocalRouting = tmp->LocalRouting;
+		ret->OldIfMetric = tmp->Metric;
+		ret->Metric = 1;
+		ret->PPPConnection = tmp->PPPConnection;
+
+		// ルーティング制御関係の計算
+		dest = IPToUINT(&tmp->DestIP);
+		gateway = IPToUINT(&tmp->GatewayIP);
+		mask = IPToUINT(&tmp->DestMask);
+		if ((dest & mask) == (gateway & mask))
+		{
+#ifdef	OS_WIN32
+			if (MsIsVista() == false)
+			{
+				// Windows 用調整
+				ret->PPPConnection = true;
+			}
+#endif	// OS_WIN32
+		}
+	}
+
+	return ret;
+}
+
+// ルーティングエントリを解放する
+void FreeRouteEntry(ROUTE_ENTRY *e)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return;
+	}
+
+	Free(e);
+}
+
+// 現在のルーティングテーブルを解析して最適なルートエントリを取得する
+ROUTE_ENTRY *GetBestRouteEntry(IP *ip)
+{
+	return GetBestRouteEntryEx(ip, 0);
+}
+ROUTE_ENTRY *GetBestRouteEntryEx(IP *ip, UINT exclude_if_id)
+{
+	ROUTE_TABLE *table;
+	ROUTE_ENTRY *e = NULL;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return NULL;
+	}
+
+	table = GetRouteTable();
+	if (table == NULL)
+	{
+		return NULL;
+	}
+
+	e = GetBestRouteEntryFromRouteTableEx(table, ip, exclude_if_id);
+	FreeRouteTable(table);
+
+	return e;
+}
+
+// 仮想 LAN カードのインターフェース ID の取得
+UINT GetVLanInterfaceID(char *tag_name)
+{
+	UINT ret = 0;
+#ifdef	OS_WIN32
+	ret = Win32GetVLanInterfaceID(tag_name);
+#else	// OS_WIN32
+	ret = UnixGetVLanInterfaceID(tag_name);
+#endif	// OS_WIN32
+	return ret;
+}
+
+// 仮想 LAN カードの列挙変数の解放
+void FreeEnumVLan(char **s)
+{
+	char *a;
+	UINT i;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	i = 0;
+	while (true)
+	{
+		a = s[i++];
+		if (a == NULL)
+		{
+			break;
+		}
+		Free(a);
+	}
+
+	Free(s);
+}
+
+// 仮想 LAN カードの列挙
+char **EnumVLan(char *tag_name)
+{
+	char **ret = NULL;
+#ifdef	OS_WIN32
+	ret = Win32EnumVLan(tag_name);
+#else	// OS_WIN32
+	ret = UnixEnumVLan(tag_name);
+#endif	// OS_WIN32
+	return ret;
+}
+
+// ルーティングテーブルを表示する
+void DebugPrintRouteTable(ROUTE_TABLE *r)
+{
+	UINT i;
+	// 引数チェック
+	if (r == NULL)
+	{
+		return;
+	}
+
+	if (IsDebug() == false)
+	{
+		return;
+	}
+
+	Debug("---- Routing Table (%u Entries) ----\n", r->NumEntry);
+
+	for (i = 0;i < r->NumEntry;i++)
+	{
+		Debug("   ");
+
+		DebugPrintRoute(r->Entry[i]);
+	}
+
+	Debug("------------------------------------\n");
+}
+
+// ルーティングテーブルエントリを表示する
+void DebugPrintRoute(ROUTE_ENTRY *e)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (e == NULL)
+	{
+		return;
+	}
+
+	if (IsDebug() == false)
+	{
+		return;
+	}
+
+	RouteToStr(tmp, sizeof(tmp), e);
+
+	Debug("%s\n", tmp);
+}
+
+// ルーティングテーブルエントリを文字列にする
+void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e)
+{
+	char dest_ip[MAX_PATH];
+	char dest_mask[MAX_PATH];
+	char gateway_ip[MAX_PATH];
+	// 引数チェック
+	if (str == NULL || e == NULL)
+	{
+		return;
+	}
+
+	IPToStr(dest_ip, sizeof(dest_ip), &e->DestIP);
+	IPToStr(dest_mask, sizeof(dest_mask), &e->DestMask);
+	IPToStr(gateway_ip, sizeof(gateway_ip), &e->GatewayIP);
+
+	Format(str, str_size, "%s/%s %s m=%u oif=%u if=%u lo=%u p=%u",
+		dest_ip, dest_mask, gateway_ip,
+		e->Metric, e->OldIfMetric, e->InterfaceID,
+		e->LocalRouting, e->PPPConnection);
+}
+
+// ルーティングテーブルの削除
+void DeleteRouteEntry(ROUTE_ENTRY *e)
+{
+	Debug("DeleteRouteEntry();\n");
+#ifdef	OS_WIN32
+	Win32DeleteRouteEntry(e);
+#else	// OS_WIN32
+	UnixDeleteRouteEntry(e);
+#endif
+}
+
+// ルーティングテーブルの追加
+bool AddRouteEntry(ROUTE_ENTRY *e)
+{
+	bool dummy = false;
+	return AddRouteEntryEx(e, &dummy);
+}
+bool AddRouteEntryEx(ROUTE_ENTRY *e, bool *already_exists)
+{
+	bool ret = false;
+	Debug("AddRouteEntryEx();\n");
+#ifdef	OS_WIN32
+	ret = Win32AddRouteEntry(e, already_exists);
+#else	// OS_WIN32
+	ret = UnixAddRouteEntry(e, already_exists);
+#endif
+	return ret;
+}
+
+// ルーティングテーブルの取得
+ROUTE_TABLE *GetRouteTable()
+{
+	ROUTE_TABLE *t = NULL;
+	UINT i;
+	BUF *buf = NewBuf();
+	UCHAR hash[MD5_SIZE];
+
+#ifdef	OS_WIN32
+	t = Win32GetRouteTable();
+#else	//OS_WIN32
+	t = UnixGetRouteTable();
+#endif	// OS_WIN32
+
+	WriteBuf(buf, &t->NumEntry, sizeof(t->NumEntry));
+
+	for (i = 0;i < t->NumEntry;i++)
+	{
+		ROUTE_ENTRY *e = t->Entry[i];
+
+		WriteBuf(buf, e, sizeof(ROUTE_ENTRY));
+	}
+
+	Hash(hash, buf->Buf, buf->Size, false);
+
+	FreeBuf(buf);
+
+	Copy(&t->HashedValue, hash, sizeof(t->HashedValue));
+
+	return t;
+}
+
+// ルーティングテーブルの解放
+void FreeRouteTable(ROUTE_TABLE *t)
+{
+	UINT i;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < t->NumEntry;i++)
+	{
+		Free(t->Entry[i]);
+	}
+	Free(t->Entry);
+	Free(t);
+}
+
+// UDP 受信
+UINT RecvFrom(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
+{
+	SOCKET s;
+	int ret, sz;
+	struct sockaddr_in addr;
+	// 引数チェック
+	if (sock == NULL || src_addr == NULL || src_port == NULL || data == NULL)
+	{
+		return false;
+	}
+	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
+	{
+		return false;
+	}
+	if (size == 0)
+	{
+		return false;
+	}
+
+	if (sock->IPv6)
+	{
+		return RecvFrom6(sock, src_addr, src_port, data, size);
+	}
+
+	s = sock->socket;
+
+	sz = sizeof(addr);
+	ret = recvfrom(s, data, size, 0, (struct sockaddr *)&addr, (int *)&sz);
+	if (ret > 0)
+	{
+		InAddrToIP(src_addr, &addr.sin_addr);
+		*src_port = (UINT)ntohs(addr.sin_port);
+
+		Lock(sock->lock);
+		{
+			sock->RecvNum++;
+			sock->RecvSize += (UINT64)ret;
+		}
+		Unlock(sock->lock);
+
+		// Debug("UDP RecvFrom: %u\n", ret);
+
+		return (UINT)ret;
+	}
+	else
+	{
+		sock->IgnoreRecvErr = false;
+
+#ifdef	OS_WIN32
+		if (WSAGetLastError() == WSAECONNRESET)
+		{
+			sock->IgnoreRecvErr = true;
+		}
+		else if (WSAGetLastError() == WSAEWOULDBLOCK)
+		{
+			return SOCK_LATER;
+		}
+		else
+		{
+			UINT e = WSAGetLastError();
+//			Debug("RecvFrom Error: %u\n", e);
+		}
+#else	// OS_WIN32
+		if (errno == ECONNREFUSED || errno == ECONNRESET)
+		{
+			sock->IgnoreRecvErr = true;
+		}
+		else if (errno == EAGAIN)
+		{
+			return SOCK_LATER;
+		}
+#endif	// OS_WIN32
+		return 0;
+	}
+}
+UINT RecvFrom6(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size)
+{
+	SOCKET s;
+	int ret, sz;
+	struct sockaddr_in6 addr;
+	// 引数チェック
+	if (sock == NULL || src_addr == NULL || src_port == NULL || data == NULL)
+	{
+		return false;
+	}
+	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
+	{
+		return false;
+	}
+	if (size == 0)
+	{
+		return false;
+	}
+
+	s = sock->socket;
+
+	sz = sizeof(addr);
+	ret = recvfrom(s, data, size, 0, (struct sockaddr *)&addr, (int *)&sz);
+	if (ret > 0)
+	{
+		InAddrToIP6(src_addr, &addr.sin6_addr);
+		src_addr->ipv6_scope_id = addr.sin6_scope_id;
+		*src_port = (UINT)ntohs(addr.sin6_port);
+
+		Lock(sock->lock);
+		{
+			sock->RecvNum++;
+			sock->RecvSize += (UINT64)ret;
+		}
+		Unlock(sock->lock);
+
+		// Debug("UDP RecvFrom: %u\n", ret);
+
+		return (UINT)ret;
+	}
+	else
+	{
+		sock->IgnoreRecvErr = false;
+
+#ifdef	OS_WIN32
+		if (WSAGetLastError() == WSAECONNRESET)
+		{
+			sock->IgnoreRecvErr = true;
+		}
+		else if (WSAGetLastError() == WSAEWOULDBLOCK)
+		{
+			return SOCK_LATER;
+		}
+		else
+		{
+			UINT e = WSAGetLastError();
+			//			Debug("RecvFrom Error: %u\n", e);
+		}
+#else	// OS_WIN32
+		if (errno == ECONNREFUSED || errno == ECONNRESET)
+		{
+			sock->IgnoreRecvErr = true;
+		}
+		else if (errno == EAGAIN)
+		{
+			return SOCK_LATER;
+		}
+#endif	// OS_WIN32
+		return 0;
+	}
+}
+
+// OpenSSL のロック
+void LockOpenSSL()
+{
+	Lock(openssl_lock);
+}
+
+// OpenSSL のロック解除
+void UnlockOpenSSL()
+{
+	Unlock(openssl_lock);
+}
+
+
+// UDP 送信
+UINT SendTo(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size)
+{
+	SOCKET s;
+	int ret;
+	struct sockaddr_in addr;
+	// 引数チェック
+	if (sock == NULL || dest_addr == NULL || dest_port == 0 || data == NULL)
+	{
+		return 0;
+	}
+	if (dest_port >= 65536)
+	{
+		return 0;
+	}
+	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
+	{
+		return 0;
+	}
+	if (size == 0)
+	{
+		return 0;
+	}
+
+	if (sock->IPv6)
+	{
+		return SendTo6(sock, dest_addr, dest_port, data, size);
+	}
+
+	if (IsIP4(dest_addr) == false)
+	{
+		return 0;
+	}
+
+	s = sock->socket;
+	Zero(&addr, sizeof(addr));
+	addr.sin_family = AF_INET;
+	addr.sin_port = htons((USHORT)dest_port);
+	IPToInAddr(&addr.sin_addr, dest_addr);
+
+	if (dest_addr->addr[0] == 255 && dest_addr->addr[1] == 255 && 
+		dest_addr->addr[2] == 255 && dest_addr->addr[3] == 255)
+	{
+		if (sock->UdpBroadcast == false)
+		{
+			bool yes = true;
+
+			sock->UdpBroadcast = true;
+
+			setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
+		}
+	}
+
+	ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
+	if (ret != (int)size)
+	{
+		sock->IgnoreSendErr = false;
+
+#ifdef	OS_WIN32
+		if (WSAGetLastError() == WSAECONNRESET)
+		{
+			sock->IgnoreSendErr = true;
+		}
+		else if (WSAGetLastError() == WSAEWOULDBLOCK)
+		{
+			return SOCK_LATER;
+		}
+		else
+		{
+			UINT e = WSAGetLastError();
+		}
+#else	// OS_WIN32
+		if (errno == ECONNREFUSED || errno == ECONNRESET)
+		{
+			sock->IgnoreRecvErr = true;
+		}
+		else if (errno == EAGAIN)
+		{
+			return SOCK_LATER;
+		}
+#endif	// OS_WIN32
+		return 0;
+	}
+
+	Lock(sock->lock);
+	{
+		sock->SendSize += (UINT64)size;
+		sock->SendNum++;
+	}
+	Unlock(sock->lock);
+
+	return ret;
+}
+UINT SendTo6(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size)
+{
+	SOCKET s;
+	int ret;
+	struct sockaddr_in6 addr;
+	UINT type;
+	// 引数チェック
+	if (sock == NULL || dest_addr == NULL || dest_port == 0 || data == NULL)
+	{
+		return 0;
+	}
+	if (dest_port >= 65536)
+	{
+		return 0;
+	}
+	if (sock->Type != SOCK_UDP || sock->socket == INVALID_SOCKET)
+	{
+		return 0;
+	}
+	if (size == 0)
+	{
+		return 0;
+	}
+
+	if (IsIP6(dest_addr) == false)
+	{
+		return 0;
+	}
+
+	s = sock->socket;
+	Zero(&addr, sizeof(addr));
+	addr.sin6_family = AF_INET6;
+	addr.sin6_port = htons((USHORT)dest_port);
+	IPToInAddr6(&addr.sin6_addr, dest_addr);
+	addr.sin6_scope_id = dest_addr->ipv6_scope_id;
+
+	type = GetIPAddrType6(dest_addr);
+
+	if (type & IPV6_ADDR_MULTICAST)
+	{
+		if (sock->UdpBroadcast == false)
+		{
+			bool yes = true;
+
+			sock->UdpBroadcast = true;
+
+			setsockopt(s, SOL_SOCKET, SO_BROADCAST, (char *)&yes, sizeof(yes));
+		}
+	}
+
+	ret = sendto(s, data, size, 0, (struct sockaddr *)&addr, sizeof(addr));
+	if (ret != (int)size)
+	{
+		sock->IgnoreSendErr = false;
+
+#ifdef	OS_WIN32
+		if (WSAGetLastError() == WSAECONNRESET)
+		{
+			sock->IgnoreSendErr = true;
+		}
+		else if (WSAGetLastError() == WSAEWOULDBLOCK)
+		{
+			return SOCK_LATER;
+		}
+		else
+		{
+			UINT e = WSAGetLastError();
+		}
+#else	// OS_WIN32
+		if (errno == ECONNREFUSED || errno == ECONNRESET)
+		{
+			sock->IgnoreRecvErr = true;
+		}
+		else if (errno == EAGAIN)
+		{
+			return SOCK_LATER;
+		}
+#endif	// OS_WIN32
+		return 0;
+	}
+
+	Lock(sock->lock);
+	{
+		sock->SendSize += (UINT64)size;
+		sock->SendNum++;
+	}
+	Unlock(sock->lock);
+
+	return ret;
+}
+
+// UDP ソケットの作成と初期化
+// port が 0 の場合は OS がランダムに割り当てる
+SOCK *NewUDP(UINT port)
+{
+	return NewUDPEx(port, false);
+}
+SOCK *NewUDPEx(UINT port, bool ipv6)
+{
+	if (ipv6 == false)
+	{
+		return NewUDP4(port);
+	}
+	else
+	{
+		return NewUDP6(port);
+	}
+}
+SOCK *NewUDP4(UINT port)
+{
+	SOCK *sock;
+	SOCKET s;
+	struct sockaddr_in addr;
+
+	s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (s == INVALID_SOCKET)
+	{
+		return NULL;
+	}
+
+	Zero(&addr, sizeof(addr));
+	addr.sin_family = AF_INET;
+	addr.sin_addr.s_addr = htonl(INADDR_ANY);
+	if (port == 0)
+	{
+		addr.sin_port = 0;
+	}
+	else
+	{
+		addr.sin_port = htons((USHORT)port);
+	}
+
+	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
+	{
+		// 失敗
+		closesocket(s);
+		return NULL;
+	}
+
+	sock = NewSock();
+
+	sock->Type = SOCK_UDP;
+	sock->Connected = false;
+	sock->AsyncMode = false;
+	sock->ServerMode = false;
+	if (port != 0)
+	{
+		sock->ServerMode = true;
+	}
+
+	sock->socket = s;
+
+	QuerySocketInformation(sock);
+
+	return sock;
+}
+SOCK *NewUDP6(UINT port)
+{
+	SOCK *sock;
+	SOCKET s;
+	struct sockaddr_in6 addr;
+
+	s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+	if (s == INVALID_SOCKET)
+	{
+		return NULL;
+	}
+
+	Zero(&addr, sizeof(addr));
+	addr.sin6_family = AF_INET6;
+	if (port == 0)
+	{
+		addr.sin6_port = 0;
+	}
+	else
+	{
+		addr.sin6_port = htons((USHORT)port);
+	}
+
+	if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) != 0)
+	{
+		// 失敗
+		closesocket(s);
+		return NULL;
+	}
+
+	sock = NewSock();
+
+	sock->Type = SOCK_UDP;
+	sock->Connected = false;
+	sock->AsyncMode = false;
+	sock->ServerMode = false;
+	sock->IPv6 = true;
+	if (port != 0)
+	{
+		sock->ServerMode = true;
+	}
+
+	sock->socket = s;
+
+	QuerySocketInformation(sock);
+
+	return sock;
+}
+
+// Select 関数
+void Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2)
+{
+#ifdef	OS_WIN32
+	Win32Select(set, timeout, c1, c2);
+#else
+	UnixSelect(set, timeout, c1, c2);
+#endif	// OS_WIN32
+}
+
+// ソケットセットにソケットを追加
+void AddSockSet(SOCKSET *set, SOCK *sock)
+{
+	// 引数チェック
+	if (set == NULL || sock == NULL)
+	{
+		return;
+	}
+	if (sock->Type == SOCK_TCP && sock->Connected == false)
+	{
+		return;
+	}
+
+	if (set->NumSocket >= MAX_SOCKSET_NUM)
+	{
+		// 上限
+		return;
+	}
+	set->Sock[set->NumSocket++] = sock;
+}
+
+// ソケットセットの初期化
+void InitSockSet(SOCKSET *set)
+{
+	// 引数チェック
+	if (set == NULL)
+	{
+		return;
+	}
+
+	Zero(set, sizeof(SOCKSET));
+}
+
+// TCP すべて受信
+bool RecvAll(SOCK *sock, void *data, UINT size, bool secure)
+{
+	UINT recv_size, sz, ret;
+	// 引数チェック
+	if (sock == NULL || data == NULL)
+	{
+		return false;
+	}
+	if (size == 0)
+	{
+		return true;
+	}
+	if (sock->AsyncMode)
+	{
+		return false;
+	}
+
+	recv_size = 0;
+
+	while (true)
+	{
+		sz = size - recv_size;
+		ret = Recv(sock, (UCHAR *)data + recv_size, sz, secure);
+		if (ret == 0)
+		{
+			return false;
+		}
+		recv_size += ret;
+		if (recv_size >= size)
+		{
+			return true;
+		}
+	}
+}
+
+// TCP 送信バッファを送信する
+bool SendNow(SOCK *sock, int secure)
+{
+	bool ret;
+	// 引数チェック
+	if (sock == NULL || sock->AsyncMode != false)
+	{
+		return false;
+	}
+	if (sock->SendBuf->Size == 0)
+	{
+		return true;
+	}
+
+	ret = SendAll(sock, sock->SendBuf->Buf, sock->SendBuf->Size, secure);
+	ClearBuf(sock->SendBuf);
+
+	return ret;
+}
+
+// TCP 送信バッファ追加
+void SendAdd(SOCK *sock, void *data, UINT size)
+{
+	// 引数チェック
+	if (sock == NULL || data == NULL || size == 0 || sock->AsyncMode != false)
+	{
+		return;
+	}
+
+	WriteBuf(sock->SendBuf, data, size);
+}
+
+// TCP すべて送信
+bool SendAll(SOCK *sock, void *data, UINT size, bool secure)
+{
+	UCHAR *buf;
+	UINT sent_size;
+	UINT ret;
+	// 引数チェック
+	if (sock == NULL || data == NULL)
+	{
+		return false;
+	}
+	if (sock->AsyncMode)
+	{
+		return false;
+	}
+	if (size == 0)
+	{
+		return true;
+	}
+
+	buf = (UCHAR *)data;
+	sent_size = 0;
+
+	while (true)
+	{
+		ret = Send(sock, buf, size - sent_size, secure);
+		if (ret == 0)
+		{
+			return false;
+		}
+		sent_size += ret;
+		buf += ret;
+		if (sent_size >= size)
+		{
+			return true;
+		}
+	}
+}
+
+// 使用したい暗号化アルゴリズム名を設定する
+void SetWantToUseCipher(SOCK *sock, char *name)
+{
+	// 引数チェック
+	if (sock == NULL || name == NULL)
+	{
+		return;
+	}
+
+	if (sock->WaitToUseCipher)
+	{
+		Free(sock->WaitToUseCipher);
+	}
+	sock->WaitToUseCipher = CopyStr(name);
+}
+
+// TCP-SSL 通信を開始する
+bool StartSSL(SOCK *sock, X *x, K *priv)
+{
+	return StartSSLEx(sock, x, priv, false);
+}
+bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls)
+{
+	X509 *x509;
+	EVP_PKEY *key;
+	UINT prev_timeout = 1024;
+
+#ifdef UNIX_SOLARIS
+	SOCKET_TIMEOUT_PARAM *ttparam;
+#endif //UNIX_SOLARIS
+
+	// 引数チェック
+	if (sock == NULL)
+	{
+		Debug("StartSSL Error: #0\n");
+		return false;
+	}
+	if (sock->Connected == false || sock->socket == INVALID_SOCKET ||
+		sock->ListenMode != false)
+	{
+		Debug("StartSSL Error: #1\n");
+		return false;
+	}
+	if (x != NULL && priv == NULL)
+	{
+		Debug("StartSSL Error: #2\n");
+		return false;
+	}
+
+	if (sock->SecureMode)
+	{
+		Debug("StartSSL Error: #3\n");
+		// すでに SSL 通信が開始されている
+		return true;
+	}
+
+	Lock(sock->ssl_lock);
+	if (sock->SecureMode)
+	{
+		Debug("StartSSL Error: #4\n");
+		// すでに SSL 通信が開始されている
+		Unlock(sock->ssl_lock);
+		return true;
+	}
+
+	Lock(openssl_lock);
+	{
+		if (sock->ServerMode)
+		{
+			SSL_CTX_set_ssl_version(ssl_ctx, SSLv23_method());
+		}
+		else
+		{
+			if (client_tls == false)
+			{
+				SSL_CTX_set_ssl_version(ssl_ctx, SSLv3_method());
+			}
+			else
+			{
+				SSL_CTX_set_ssl_version(ssl_ctx, TLSv1_client_method());
+			}
+		}
+		sock->ssl = SSL_new(ssl_ctx);
+		SSL_set_fd(sock->ssl, (int)sock->socket);
+	}
+	Unlock(openssl_lock);
+
+	if (x != NULL)
+	{
+		// 証明書と秘密鍵のチェック
+		if (CheckXandK(x, priv))
+		{
+			// 証明書を使用する
+			x509 = x->x509;
+			key = priv->pkey;
+
+			Lock(openssl_lock);
+			{
+				SSL_use_certificate(sock->ssl, x509);
+				SSL_use_PrivateKey(sock->ssl, key);
+			}
+			Unlock(openssl_lock);
+		}
+	}
+
+	if (sock->WaitToUseCipher != NULL)
+	{
+		// 使用したい暗号化アルゴリズム名を設定する
+		Lock(openssl_lock);
+		{
+			SSL_set_cipher_list(sock->ssl, sock->WaitToUseCipher);
+		}
+		Unlock(openssl_lock);
+	}
+
+	if (sock->ServerMode)
+	{
+//		Lock(ssl_connect_lock);
+
+// SOLARIS用タイムアウトスレッドの起動
+#ifdef UNIX_SOLARIS
+		ttparam = NewSocketTimeout(sock);
+#endif // UNIX_SOLARIS
+
+		// サーバーモード
+		if (SSL_accept(sock->ssl) <= 0)
+		{
+
+// タイムアウトスレッドの停止
+#ifdef UNIX_SOLARIS
+			FreeSocketTimeout(ttparam);
+#endif // UNIX_SOLARIS
+
+			//			Unlock(ssl_connect_lock);
+			// SSL-Accept 失敗
+			Lock(openssl_lock);
+			{
+				SSL_free(sock->ssl);
+			}
+			Unlock(openssl_lock);
+
+			Unlock(sock->ssl_lock);
+			Debug("StartSSL Error: #5\n");
+			return false;
+		}
+
+// タイムアウトスレッドの停止
+#ifdef UNIX_SOLARIS
+		FreeSocketTimeout(ttparam);
+#endif // UNIX_SOLARIS
+
+		//		Unlock(ssl_connect_lock);
+	}
+	else
+	{
+		prev_timeout = GetTimeout(sock);
+		SetTimeout(sock, TIMEOUT_SSL_CONNECT);
+		Lock(ssl_connect_lock);
+		// クライアントモード
+		if (SSL_connect(sock->ssl) <= 0)
+		{
+			Unlock(ssl_connect_lock);
+			// SSL-connect 失敗
+			Lock(openssl_lock);
+			{
+				SSL_free(sock->ssl);
+			}
+			Unlock(openssl_lock);
+
+			Unlock(sock->ssl_lock);
+			Debug("StartSSL Error: #5\n");
+			SetTimeout(sock, prev_timeout);
+			return false;
+		}
+		Unlock(ssl_connect_lock);
+		SetTimeout(sock, prev_timeout);
+	}
+
+	// SSL 通信が開始された
+	sock->SecureMode = true;
+
+	// リモートホストの証明書を取得する
+	Lock(openssl_lock);
+	{
+		x509 = SSL_get_peer_certificate(sock->ssl);
+	}
+	Unlock(openssl_lock);
+
+	if (x509 == NULL)
+	{
+		// リモートホストに証明書は存在しない
+		sock->RemoteX = NULL;
+	}
+	else
+	{
+		// 証明書を取得できた
+		sock->RemoteX = X509ToX(x509);
+	}
+
+	// ローカルホストの証明書を取得する
+	Lock(openssl_lock);
+	{
+		x509 = SSL_get_certificate(sock->ssl);
+	}
+	Unlock(openssl_lock);
+
+	if (x509 == NULL)
+	{
+		// リモートホストに証明書は存在しない
+		sock->LocalX = NULL;
+	}
+	else
+	{
+		X *local_x;
+		// 証明書を取得できた
+		local_x = X509ToX(x509);
+		local_x->do_not_free = true;
+		sock->LocalX = CloneX(local_x);
+		FreeX(local_x);
+	}
+
+	// 自動再試行モード
+	SSL_set_mode(sock->ssl, SSL_MODE_AUTO_RETRY);
+
+	// へんなフラグ
+	SSL_set_mode(sock->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+
+	// 暗号化に使用しているアルゴリズム名を取得
+	Lock(openssl_lock);
+	{
+		sock->CipherName = CopyStr((char *)SSL_get_cipher(sock->ssl));
+	}
+	Unlock(openssl_lock);
+
+	Unlock(sock->ssl_lock);
+
+	return true;
+}
+
+// TCP-SSL 受信
+UINT SecureRecv(SOCK *sock, void *data, UINT size)
+{
+	SOCKET s;
+	int ret, e = 0;
+	SSL *ssl;
+
+#ifdef UNIX_SOLARIS
+	SOCKET_TIMEOUT_PARAM *ttparam;
+#endif //UNIX_SOLARIS
+
+	s = sock->socket;
+	ssl = sock->ssl;
+
+	if (sock->AsyncMode)
+	{
+		// 非同期モードの場合はデータが 1 バイトでも読み出し可能かどうか確認する。
+		// 読み出し可能なデータが無い場合に read をしてしまうとブロッキングするため
+		// それは避けなければならない。
+		char c;
+		Lock(sock->ssl_lock);
+		{
+			if (sock->Connected == false)
+			{
+				Unlock(sock->ssl_lock);
+				Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
+				return 0;
+			}
+			ret = SSL_peek(ssl, &c, sizeof(c));
+		}
+		Unlock(sock->ssl_lock);
+		if (ret == 0)
+		{
+			// 通信が切れておる
+			Disconnect(sock);
+			Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
+			return 0;
+		}
+		if (ret < 0)
+		{
+			// エラーが発生した
+			e = SSL_get_error(ssl, ret);
+			if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
+			{
+				// パケットがまだ届いていない、つまり read してはいけない
+				return SOCK_LATER;
+			}
+		}
+	}
+
+	// 受信する
+	Lock(sock->ssl_lock);
+	{
+		if (sock->Connected == false)
+		{
+			Unlock(sock->ssl_lock);
+			Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
+			return 0;
+		}
+
+#ifdef	OS_UNIX
+		if (sock->AsyncMode == false)
+		{
+			sock->CallingThread = pthread_self();
+		}
+#endif	// OS_UNIX
+
+// SOLARIS用タイムアウトスレッドの起動
+#ifdef UNIX_SOLARIS
+		ttparam = NewSocketTimeout(sock);
+#endif // UNIX_SOLARIS
+
+		ret = SSL_read(ssl, data, size);
+
+// タイムアウトスレッドの停止
+#ifdef UNIX_SOLARIS
+		FreeSocketTimeout(ttparam);
+#endif // UNIX_SOLARIS
+
+
+#ifdef	OS_UNIX
+		if (sock->AsyncMode == false)
+		{
+			sock->CallingThread = 0;
+		}
+#endif	// OS_UNIX
+
+		if (ret < 0)
+		{
+			e = SSL_get_error(ssl, ret);
+		}
+
+	}
+	Unlock(sock->ssl_lock);
+	if (ret > 0)
+	{
+		// 受信成功
+		sock->RecvSize += (UINT64)ret;
+		sock->RecvNum++;
+		return (UINT)ret;
+	}
+	if (ret == 0)
+	{
+		// 通信切断
+		Disconnect(sock);
+		Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
+		return 0;
+	}
+	if (sock->AsyncMode)
+	{
+		if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
+		{
+			// パケットがまだ届いていない
+			return SOCK_LATER;
+		}
+	}
+	Disconnect(sock);
+	Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
+	return 0;
+}
+
+// TCP-SSL 送信
+UINT SecureSend(SOCK *sock, void *data, UINT size)
+{
+	SOCKET s;
+	int ret, e;
+	SSL *ssl;
+	s = sock->socket;
+	ssl = sock->ssl;
+
+	if (sock->AsyncMode)
+	{
+		// 非同期モード
+		SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE);
+	}
+
+	// 送信
+	Lock(sock->ssl_lock);
+	{
+		if (sock->Connected == false)
+		{
+			Unlock(sock->ssl_lock);
+			Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
+			return 0;
+		}
+
+		ret = SSL_write(ssl, data, size);
+		if (ret < 0)
+		{
+			e = SSL_get_error(ssl, ret);
+		}
+	}
+	Unlock(sock->ssl_lock);
+
+	if (ret > 0)
+	{
+		// 送信成功
+		sock->SendSize += (UINT64)ret;
+		sock->SendNum++;
+		sock->WriteBlocked = false;
+		return (UINT)ret;
+	}
+	if (ret == 0)
+	{
+		// 切断
+		Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
+		Disconnect(sock);
+		return 0;
+	}
+
+	if (sock->AsyncMode)
+	{
+		// エラー値の確認
+		if (e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE || e == SSL_ERROR_SSL)
+		{
+			sock->WriteBlocked = true;
+			return SOCK_LATER;
+		}
+		Debug("%s %u e=%u\n", __FILE__, __LINE__, e);
+	}
+	//Debug("%s %u SecureRecv() Disconnect\n", __FILE__, __LINE__);
+	Disconnect(sock);
+	return 0;
+}
+
+// TCP 受信
+UINT Recv(SOCK *sock, void *data, UINT size, bool secure)
+{
+	SOCKET s;
+	int ret;
+
+#ifdef UNIX_SOLARIS
+	SOCKET_TIMEOUT_PARAM *ttparam;
+#endif //UNIX_SOLARIS
+
+	// 引数チェック
+	if (sock == NULL || data == NULL || size == 0)
+	{
+		return 0;
+	}
+	if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
+		sock->socket == INVALID_SOCKET)
+	{
+		return 0;
+	}
+	if (secure != false && sock->SecureMode == false)
+	{
+		return 0;
+	}
+
+	if (secure)
+	{
+		return SecureRecv(sock, data, size);
+	}
+
+	// 受信
+	s = sock->socket;
+
+
+#ifdef	OS_UNIX
+	if (sock->AsyncMode == false)
+	{
+		sock->CallingThread = pthread_self();
+	}
+#endif	// OS_UNIX
+
+// SOLARIS用タイムアウトスレッドの開始
+#ifdef UNIX_SOLARIS
+	ttparam = NewSocketTimeout(sock);
+#endif // UNIX_SOLARIS
+
+	ret = recv(s, data, size, 0);
+
+// タイムアウトスレッドの停止
+#ifdef UNIX_SOLARIS
+	FreeSocketTimeout(ttparam);
+#endif // UNIX_SOLARIS
+
+#ifdef	OS_UNIX
+	if (sock->AsyncMode == false)
+	{
+		sock->CallingThread = 0;
+	}
+#endif	// OS_UNIX
+
+	if (ret > 0)
+	{
+		// 受信成功
+		Lock(sock->lock);
+		{
+			sock->RecvSize += (UINT64)ret;
+			sock->SendNum++;
+		}
+		Unlock(sock->lock);
+		return (UINT)ret;
+	}
+
+	// 送信失敗
+	if (sock->AsyncMode)
+	{
+		// 非同期モードの場合、エラーを調べる
+		if (ret == SOCKET_ERROR)
+		{
+#ifdef	OS_WIN32
+			if (WSAGetLastError() == WSAEWOULDBLOCK)
+			{
+				// ブロッキングしている
+				return SOCK_LATER;
+			}
+			else
+			{
+				Debug("Socket Error: %u\n", WSAGetLastError());
+			}
+#else	// OS_WIN32
+			if (errno == EAGAIN)
+			{
+				// ブロッキングしている
+				return SOCK_LATER;
+			}
+#endif	// OS_WIN32
+		}
+	}
+
+	// 切断された
+	Disconnect(sock);
+	return 0;
+}
+
+// TCP 送信
+UINT Send(SOCK *sock, void *data, UINT size, bool secure)
+{
+	SOCKET s;
+	int ret;
+	// 引数チェック
+	if (sock == NULL || data == NULL || size == 0)
+	{
+		return 0;
+	}
+	size = MIN(size, MAX_SEND_BUF_MEM_SIZE);
+	if (sock->Type != SOCK_TCP || sock->Connected == false || sock->ListenMode != false ||
+		sock->socket == INVALID_SOCKET)
+	{
+		return 0;
+	}
+	if (secure != false && sock->SecureMode == false)
+	{
+		return 0;
+	}
+
+	if (secure)
+	{
+		return SecureSend(sock, data, size);
+	}
+
+	// 送信
+	s = sock->socket;
+	ret = send(s, data, size, 0);
+	if (ret > 0)
+	{
+		// 送信成功
+		Lock(sock->lock);
+		{
+			sock->SendSize += (UINT64)ret;
+			sock->SendNum++;
+		}
+		Unlock(sock->lock);
+		sock->WriteBlocked = false;
+		return (UINT)ret;
+	}
+
+	// 送信失敗
+	if (sock->AsyncMode)
+	{
+		// 非同期モードの場合、エラーを調べる
+		if (ret == SOCKET_ERROR)
+		{
+#ifdef	OS_WIN32
+			if (WSAGetLastError() == WSAEWOULDBLOCK)
+			{
+				// ブロッキングしている
+				sock->WriteBlocked = true;
+				return SOCK_LATER;
+			}
+			else
+			{
+				Debug("Socket Error: %u\n", WSAGetLastError());
+			}
+#else	// OS_WIN32
+			if (errno == EAGAIN)
+			{
+				// ブロッキングしている
+				sock->WriteBlocked = true;
+				return SOCK_LATER;
+			}
+#endif	// OS_WIN32
+		}
+	}
+
+	// 切断された
+	Disconnect(sock);
+	return 0;
+}
+
+// タイムアウトの取得 (ミリ秒)
+UINT GetTimeout(SOCK *sock)
+{
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return INFINITE;
+	}
+	if (sock->Type != SOCK_TCP)
+	{
+		return INFINITE;
+	}
+
+	return sock->TimeOut;
+}
+
+// タイムアウト時間の設定 (ミリ秒)
+void SetTimeout(SOCK *sock, UINT timeout)
+{
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return;
+	}
+	if (sock->Type != SOCK_TCP)
+	{
+		return;
+	}
+
+	if (timeout == INFINITE)
+	{
+		timeout = TIMEOUT_INFINITE;
+	}
+
+	sock->TimeOut = timeout;
+
+//	Debug("SetTimeout(%u)\n",timeout);
+
+#ifdef OS_WIN32
+	setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(UINT));
+	setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(UINT));
+#endif
+
+#ifdef OS_UNIX
+#ifndef UNIX_SOLARIS
+	{
+		struct timeval tv_timeout;
+
+		tv_timeout.tv_sec = timeout / 1000; // miliseconds to seconds
+		tv_timeout.tv_usec = (timeout % 1000) * 1000; // miliseconds to microseconds
+
+		setsockopt(sock->socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
+		setsockopt(sock->socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv_timeout, sizeof(tv_timeout));
+	}
+#endif // UNIX_SOLARIS
+#endif // OS_UNIX
+}
+
+// 接続受諾初期化
+void AcceptInit(SOCK *s)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	Zero(tmp, sizeof(tmp));
+	if (GetHostName(tmp, sizeof(tmp), &s->RemoteIP) == false ||
+		IsEmptyStr(tmp))
+	{
+		IPToStr(tmp, sizeof(tmp), &s->RemoteIP);
+	}
+
+	s->RemoteHostname = CopyStr(tmp);
+}
+
+// TCP 接続受諾
+SOCK *Accept(SOCK *sock)
+{
+	SOCK *ret;
+	SOCKET s, new_socket;
+	int size;
+	struct sockaddr_in addr;
+	bool true_flag = true;
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return NULL;
+	}
+	if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
+	{
+		return NULL;
+	}
+	if (sock->CancelAccept)
+	{
+		return NULL;
+	}
+	if (sock->IPv6)
+	{
+		return Accept6(sock);
+	}
+
+	s = sock->socket;
+	if (s == INVALID_SOCKET)
+	{
+		return NULL;
+	}
+	Zero(&addr, sizeof(addr));
+	size = sizeof(addr);
+
+#ifdef	OS_UNIX
+	sock->CallingThread = pthread_self();
+#endif	// OS_UNIX
+
+	new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
+
+#ifdef	OS_UNIX
+	sock->CallingThread = 0;
+#endif	// OS_UNIX
+
+	if (new_socket == INVALID_SOCKET)
+	{
+		return NULL;
+	}
+	if (sock->CancelAccept)
+	{
+		closesocket(new_socket);
+		return NULL;
+	}
+
+	ret = NewSock();
+	ret->socket = new_socket;
+	ret->Connected = true;
+	ret->AsyncMode = false;
+	ret->Type = SOCK_TCP;
+	ret->ServerMode = true;
+	ret->SecureMode = false;
+
+	// TCP オプションの設定
+	setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
+
+	SetSockPriorityHigh(ret);
+
+	// タイムアウト値の初期化
+	SetTimeout(ret, TIMEOUT_INFINITE);
+
+	// ソケット情報
+	QuerySocketInformation(ret);
+
+	AddIpClient(&ret->RemoteIP);
+
+	return ret;
+}
+SOCK *Accept6(SOCK *sock)
+{
+	SOCK *ret;
+	SOCKET s, new_socket;
+	int size;
+	struct sockaddr_in6 addr;
+	bool true_flag = true;
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return NULL;
+	}
+	if (sock->ListenMode == false || sock->Type != SOCK_TCP || sock->ServerMode == false)
+	{
+		return NULL;
+	}
+	if (sock->CancelAccept)
+	{
+		return NULL;
+	}
+	if (sock->IPv6 == false)
+	{
+		return NULL;
+	}
+
+	s = sock->socket;
+	if (s == INVALID_SOCKET)
+	{
+		return NULL;
+	}
+	Zero(&addr, sizeof(addr));
+	size = sizeof(addr);
+
+#ifdef	OS_UNIX
+	sock->CallingThread = pthread_self();
+#endif	// OS_UNIX
+
+	new_socket = accept(s, (struct sockaddr *)&addr,(int *)&size);
+
+#ifdef	OS_UNIX
+	sock->CallingThread = 0;
+#endif	// OS_UNIX
+
+	if (new_socket == INVALID_SOCKET)
+	{
+		return NULL;
+	}
+	if (sock->CancelAccept)
+	{
+		closesocket(new_socket);
+		return NULL;
+	}
+
+	ret = NewSock();
+	ret->socket = new_socket;
+	ret->Connected = true;
+	ret->AsyncMode = false;
+	ret->Type = SOCK_TCP;
+	ret->ServerMode = true;
+	ret->SecureMode = false;
+
+	// TCP オプションの設定
+	setsockopt(ret->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
+
+	SetSockPriorityHigh(ret);
+
+	// タイムアウト値の初期化
+	SetTimeout(ret, TIMEOUT_INFINITE);
+
+	// ソケット情報
+	QuerySocketInformation(ret);
+
+	AddIpClient(&ret->RemoteIP);
+
+	return ret;
+}
+
+// TCP 待ち受け (IPv6)
+SOCK *Listen6(UINT port)
+{
+	return ListenEx6(port, false);
+}
+SOCK *ListenEx6(UINT port, bool local_only)
+{
+	SOCKET s;
+	SOCK *sock;
+	struct sockaddr_in6 addr;
+	struct in6_addr in;
+	bool true_flag = true;
+	IP localhost;
+	// 引数チェック
+	if (port == 0 || port >= 65536)
+	{
+		return NULL;
+	}
+
+	// 初期化
+	Zero(&addr, sizeof(addr));
+	Zero(&in, sizeof(in));
+	GetLocalHostIP6(&localhost);
+
+	addr.sin6_port = htons((UINT)port);
+	addr.sin6_family = AF_INET6;
+
+	if (local_only)
+	{
+		IPToInAddr6(&addr.sin6_addr, &localhost);
+	}
+
+	// ソケットの作成
+	s = socket(AF_INET6, SOCK_STREAM, 0);
+	if (s == INVALID_SOCKET)
+	{
+		return NULL;
+	}
+
+#ifdef	OS_UNIX
+	// UNIX 系では IPv6 Only フラグを立てる必要がある
+	setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &true_flag, sizeof(true_flag));
+#endif	// OS_UNIX
+
+	//SetSocketSendRecvBufferSize(s, SOCKET_BUFFER_SIZE);
+
+#ifdef	OS_UNIX
+	// Windows 系 OS は REUSEADDR の実装にバグがあるっぽいので
+	// UNIX 系のみ有効にした。
+	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
+#endif	// OS_UNIX
+
+	if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in6)) != 0)
+	{
+		// bind 失敗
+		closesocket(s);
+		return NULL;
+	}
+	if (listen(s, SOMAXCONN))
+	{
+		// listen 失敗
+		closesocket(s);
+		return NULL;
+	}
+
+	// 成功
+	sock = NewSock();
+	sock->Connected = false;
+	sock->AsyncMode = false;
+	sock->ServerMode = true;
+	sock->Type = SOCK_TCP;
+	sock->socket = s;
+	sock->ListenMode = true;
+	sock->SecureMode = false;
+	sock->LocalPort = port;
+	sock->IPv6 = true;
+
+	return sock;
+}
+
+// TCP 待ち受け
+SOCK *Listen(UINT port)
+{
+	return ListenEx(port, false);
+}
+SOCK *ListenEx(UINT port, bool local_only)
+{
+	SOCKET s;
+	SOCK *sock;
+	struct sockaddr_in addr;
+	struct in_addr in;
+	bool true_flag = true;
+	IP localhost;
+	// 引数チェック
+	if (port == 0 || port >= 65536)
+	{
+		return NULL;
+	}
+
+	// 初期化
+	Zero(&addr, sizeof(addr));
+	Zero(&in, sizeof(in));
+	SetIP(&localhost, 127, 0, 0, 1);
+
+	addr.sin_port = htons((UINT)port);
+	*((UINT *)&addr.sin_addr) = htonl(INADDR_ANY);
+	addr.sin_family = AF_INET;
+
+	if (local_only)
+	{
+		IPToInAddr(&addr.sin_addr, &localhost);
+	}
+
+	// ソケットの作成
+	s = socket(AF_INET, SOCK_STREAM, 0);
+	if (s == INVALID_SOCKET)
+	{
+		return NULL;
+	}
+
+	//SetSocketSendRecvBufferSize(s, SOCKET_BUFFER_SIZE);
+
+#ifdef	OS_UNIX
+	// Windows 系 OS は REUSEADDR の実装にバグがあるっぽいので
+	// UNIX 系のみ有効にした。
+	setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
+#endif	// OS_UNIX
+
+	if (bind(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) != 0)
+	{
+		// bind 失敗
+		closesocket(s);
+		return NULL;
+	}
+	if (listen(s, SOMAXCONN))
+	{
+		// listen 失敗
+		closesocket(s);
+		return NULL;
+	}
+
+	// 成功
+	sock = NewSock();
+	sock->Connected = false;
+	sock->AsyncMode = false;
+	sock->ServerMode = true;
+	sock->Type = SOCK_TCP;
+	sock->socket = s;
+	sock->ListenMode = true;
+	sock->SecureMode = false;
+	sock->LocalPort = port;
+
+	return sock;
+}
+
+// TCP 切断
+void Disconnect(SOCK *sock)
+{
+	SOCKET s;
+	bool true_flag = true;
+	bool false_flag = false;
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return;
+	}
+
+	sock->Disconnecting = true;
+
+#ifdef	OS_UNIX
+	UnixFreeAsyncSocket(sock);
+#endif	// UnixFreeAsyncSocket
+
+	if (sock->Type == SOCK_TCP && sock->ListenMode)
+	{
+		// Listen 中のソケットの場合は localhost に対して接続する
+		sock->CancelAccept = true;
+
+		if (sock->IPv6 == false)
+		{
+			CheckTCPPort("127.0.0.1", sock->LocalPort);
+		}
+		else
+		{
+			CheckTCPPort("::1", sock->LocalPort);
+		}
+	}
+
+	Lock(disconnect_function_lock);
+
+	Lock(sock->disconnect_lock);
+
+	if (sock->Type == SOCK_TCP)
+	{
+		if (sock->socket != INVALID_SOCKET)
+		{
+			// 強制切断フラグ
+			#ifdef	SO_DONTLINGER
+				setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
+			#else	// SO_DONTLINGER
+				setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
+			#endif	// SO_DONTLINGER
+//			setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
+		}
+
+		// TCP ソケット
+		Lock(sock->lock);
+		{
+			if (sock->socket == INVALID_SOCKET)
+			{
+				Unlock(sock->lock);
+				Unlock(sock->disconnect_lock);
+				Unlock(disconnect_function_lock);
+				return;
+			}
+			s = sock->socket;
+
+			if (sock->Connected)
+			{
+				struct linger ling;
+				Zero(&ling, sizeof(ling));
+
+
+#if	0
+				// SSL 切断
+				Lock(sock->ssl_lock);
+				{
+					if (sock->SecureMode)
+					{
+						SSL_shutdown(sock->ssl);
+					}
+				}
+				Unlock(sock->ssl_lock);
+#endif
+				// 切断
+				shutdown(s, 2);
+			}
+
+			// ソケットを閉じる
+			closesocket(s);
+
+#ifdef	OS_UNIX
+#ifdef	FIX_SSL_BLOCKING
+			if (sock->CallingThread != NULL)
+			{
+				pthread_kill(sock->CallingThread, 64);
+			}
+#endif	// FIX_SSL_BLOCKING
+#endif	// OS_UNIX
+
+			// SSL を解放
+			Lock(sock->ssl_lock);
+			{
+				if (sock->SecureMode)
+				{
+					if (sock->ssl != NULL)
+					{
+						Lock(openssl_lock);
+						{
+							SSL_free(sock->ssl);
+						}
+						Unlock(openssl_lock);
+						sock->ssl = NULL;
+					}
+					sock->Connected = false;
+					// 証明書を解放
+					if (sock->RemoteX != NULL)
+					{
+						FreeX(sock->RemoteX);
+						sock->RemoteX = NULL;
+					}
+					if (sock->LocalX != NULL)
+					{
+						FreeX(sock->LocalX);
+						sock->LocalX = NULL;
+					}
+
+					// 暗号化アルゴリズム名
+					if (sock->CipherName != NULL)
+					{
+						Free(sock->CipherName);
+						sock->CipherName = NULL;
+					}
+					sock->SecureMode = false;
+				}
+			}
+			Unlock(sock->ssl_lock);
+
+			// 初期化
+			sock->socket = INVALID_SOCKET;
+			sock->Type = 0;
+			sock->AsyncMode = false;
+			sock->Connected = false;
+			sock->ListenMode = false;
+			sock->SecureMode = false;
+
+			if (sock->ServerMode && sock->ListenMode == false)
+			{
+				DelIpClient(&sock->RemoteIP);
+			}
+		}
+		Unlock(sock->lock);
+	}
+	else if (sock->Type == SOCK_UDP)
+	{
+		// UDP ソケット
+		Lock(sock->lock);
+		{
+			if (sock->socket == INVALID_SOCKET)
+			{
+				Unlock(sock->lock);
+				Unlock(sock->disconnect_lock);
+				Unlock(disconnect_function_lock);
+				return;
+			}
+
+			s = sock->socket;
+
+			// ソケットを閉じる
+			closesocket(s);
+
+			// 初期化
+			sock->socket = INVALID_SOCKET;
+			sock->Type = 0;
+			sock->AsyncMode = false;
+			sock->Connected = false;
+			sock->ListenMode = false;
+			sock->SecureMode = false;
+		}
+		Unlock(sock->lock);
+	}
+	Unlock(sock->disconnect_lock);
+
+	Unlock(disconnect_function_lock);
+}
+
+typedef struct TCP_PORT_CHECK
+{
+	REF *ref;
+	char hostname[MAX_SIZE];
+	UINT port;
+	bool ok;
+} TCP_PORT_CHECK;
+
+// TCP ポートチェック用スレッド
+void CheckTCPPortThread(THREAD *thread, void *param)
+{
+	TCP_PORT_CHECK *c;
+	SOCK *s;
+	// 引数チェック
+	if (thread == NULL || param == NULL)
+	{
+		return;
+	}
+
+	c = (TCP_PORT_CHECK *)param;
+	AddRef(c->ref);
+	NoticeThreadInit(thread);
+
+	AddWaitThread(thread);
+
+	s = Connect(c->hostname, c->port);
+	if (s != NULL)
+	{
+		c->ok = true;
+		Disconnect(s);
+		ReleaseSock(s);
+	}
+
+	if (Release(c->ref) == 0)
+	{
+		Free(c);
+	}
+
+	DelWaitThread(thread);
+}
+
+// TCP ポートに接続可能かどうかチェックする
+bool CheckTCPPortEx(char *hostname, UINT port, UINT timeout)
+{
+	SOCK *s;
+	// 引数チェック
+	if (hostname == NULL || port == 0 || port >= 65536)
+	{
+		return false;
+	}
+
+	if (timeout == 0)
+	{
+		timeout = TIMEOUT_TCP_PORT_CHECK;
+	}
+
+	s = ConnectEx(hostname, port, timeout);
+	if (s == NULL)
+	{
+		return false;
+	}
+	else
+	{
+		Disconnect(s);
+		ReleaseSock(s);
+		return true;
+	}
+}
+bool CheckTCPPort(char *hostname, UINT port)
+{
+	return CheckTCPPortEx(hostname, port, TIMEOUT_TCP_PORT_CHECK);
+}
+
+#ifdef	OS_UNIX
+// タイムアウト付き接続 (UNIX 版)
+int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
+{
+	SOCKSET set;
+	bool ok = false;
+	UINT64 start_time;
+	// 引数チェック
+	if (s == INVALID_SOCKET || addr == NULL)
+	{
+		return -1;
+	}
+	if (timeout == 0)
+	{
+		timeout = TIMEOUT_TCP_PORT_CHECK;
+	}
+
+	UnixSetSocketNonBlockingMode(s, true);
+
+	start_time = Tick64();
+
+	while (true)
+	{
+		int ret;
+		ret = connect(s, addr, size);
+		if (ret == 0 || errno == EISCONN)
+		{
+			ok = true;
+			break;
+		}
+		else
+		{
+			if (((start_time + (UINT64)timeout) <= Tick64()) || (errno != EAGAIN && errno != EINPROGRESS && errno != EALREADY))
+			{
+				// 失敗
+				break;
+			}
+			else if (*cancel_flag)
+			{
+				// キャンセル
+				break;
+			}
+			else
+			{
+				// 接続中
+				SleepThread(50);
+				UnixSelectInner(1, (UINT *)&s, 1, (UINT *)&s, 100);
+			}
+		}
+	}
+
+	UnixSetSocketNonBlockingMode(s, false);
+
+	if (ok)
+	{
+		return 0;
+	}
+	else
+	{
+		return -1;
+	}
+}
+#else
+// タイムアウト付き接続 (Win32 版)
+int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag)
+{
+	UINT64 start_time;
+	bool ok = false;
+	bool timeouted = false;
+	WSAEVENT hEvent;
+	UINT zero = 0;
+	UINT tmp = 0;
+	UINT ret_size = 0;
+	bool is_nt = false;
+	// 引数チェック
+	if (s == INVALID_SOCKET || addr == NULL)
+	{
+		return -1;
+	}
+	if (timeout == 0)
+	{
+		timeout = TIMEOUT_TCP_PORT_CHECK;
+	}
+
+	is_nt = OS_IS_WINDOWS_NT(GetOsInfo()->OsType);
+
+	// イベントを作成
+	hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+	// ソケットをイベントに関連付ける
+	WSAEventSelect(s, hEvent, FD_CONNECT);
+
+	start_time = Tick64();
+
+	while (true)
+	{
+		int ret;
+		
+		ret = connect(s, addr, size);
+
+		if (ret == 0)
+		{
+			ok = true;
+			break;
+		}
+		else
+		{
+			int err = WSAGetLastError();
+			//Debug("err=%u\n", err);
+			//Debug("cancel_flag=%u\n", *cancel_flag);
+			if (timeouted && ((err == WSAEALREADY) || (err == WSAEWOULDBLOCK && !is_nt)))
+			{
+				// タイムアウト
+				ok = false;
+				break;
+			}
+			if (*cancel_flag)
+			{
+				// キャンセル
+				ok = false;
+				break;
+			}
+			if (err == WSAEISCONN || (err == WSAEINVAL && is_nt))
+			{
+				ok = true;
+				break;
+			}
+			if (((start_time + (UINT64)timeout) <= Tick64()) || (err != WSAEWOULDBLOCK && err != WSAEALREADY && (is_nt || err != WSAEINVAL)))
+			{
+				// 失敗 (タイムアウト)
+				break;
+			}
+			else
+			{
+				SleepThread(10);
+				// 接続中
+				if (WaitForSingleObject(hEvent, 100) == WAIT_OBJECT_0)
+				{
+					timeouted = true;
+				}
+			}
+		}
+	}
+
+	// ソケットをイベントから外す
+	WSAEventSelect(s, hEvent, 0);
+
+	// 同期ソケットに戻す
+	WSAIoctl(s, FIONBIO, &zero, sizeof(zero), &tmp, sizeof(tmp), &ret_size, NULL, NULL);
+
+	// イベントを閉じる
+	CloseHandle(hEvent);
+
+	if (ok)
+	{
+		return 0;
+	}
+	else
+	{
+		return -1;
+	}
+}
+#endif	// OS_UNIX
+
+// ソケットのパケットの優先順位を向上させる (未使用)
+void SetSockPriorityHigh(SOCK *s)
+{
+	int value;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	value = 16;
+
+#ifdef	IP_TOS
+	//setsockopt(s->socket, IPPROTO_IP, IP_TOS, (char *)&value, sizeof(int));
+#endif	// IP_TOS
+}
+
+// TCP 接続
+SOCK *Connect(char *hostname, UINT port)
+{
+	return ConnectEx(hostname, port, 0);
+}
+SOCK *ConnectEx(char *hostname, UINT port, UINT timeout)
+{
+	return ConnectEx2(hostname, port, timeout, NULL);
+}
+SOCK *ConnectEx2(char *hostname, UINT port, UINT timeout, bool *cancel_flag)
+{
+	SOCK *sock;
+	SOCKET s;
+	struct linger ling;
+	struct sockaddr_in sockaddr4;
+	struct in_addr addr4;
+	IP ip4;
+	struct sockaddr_in6 sockaddr6;
+	struct in6_addr addr6;
+	IP ip6;
+	bool true_flag = true;
+	bool false_flag = false;
+	char tmp[MAX_SIZE];
+	IP current_ip;
+	bool is_ipv6 = false;
+	bool dummy = false;
+	// 引数チェック
+	if (hostname == NULL || port == 0 || port >= 65536)
+	{
+		return NULL;
+	}
+	if (timeout == 0)
+	{
+		timeout = TIMEOUT_TCP_PORT_CHECK;
+	}
+	if (cancel_flag == NULL)
+	{
+		cancel_flag = &dummy;
+	}
+
+	Zero(&current_ip, sizeof(current_ip));
+
+	Zero(&sockaddr4, sizeof(sockaddr4));
+	Zero(&addr4, sizeof(addr4));
+	Zero(&ip4, sizeof(ip4));
+
+	Zero(&sockaddr6, sizeof(sockaddr6));
+	Zero(&addr6, sizeof(addr6));
+	Zero(&ip6, sizeof(ip6));
+
+	// 正引き
+	if (GetIP46Ex(&ip4, &ip6, hostname, 0, cancel_flag) == false)
+	{
+		return NULL;
+	}
+
+	s = INVALID_SOCKET;
+
+	// IPv4 で接続を試行する
+	if (IsZeroIp(&ip4) == false)
+	{
+		// sockaddr_in の生成
+		IPToInAddr(&addr4, &ip4);
+		sockaddr4.sin_port = htons((USHORT)port);
+		sockaddr4.sin_family = AF_INET;
+		sockaddr4.sin_addr.s_addr = addr4.s_addr;
+
+		// ソケット作成
+		s = socket(AF_INET, SOCK_STREAM, 0);
+		if (s != INVALID_SOCKET)
+		{
+			// 接続
+			if (connect_timeout(s, (struct sockaddr *)&sockaddr4, sizeof(struct sockaddr_in), timeout, cancel_flag) != 0)
+			{
+				// 接続失敗
+				closesocket(s);
+				s = INVALID_SOCKET;
+			}
+			else
+			{
+				Copy(&current_ip, &ip4, sizeof(IP));
+			}
+		}
+	}
+
+	// IPv6 で接続を試行する
+	if (s == INVALID_SOCKET && IsZeroIp(&ip6) == false)
+	{
+		// sockaddr_in6 の生成
+		IPToInAddr6(&addr6, &ip6);
+		sockaddr6.sin6_port = htons((USHORT)port);
+		sockaddr6.sin6_family = AF_INET6;
+		sockaddr6.sin6_scope_id = ip6.ipv6_scope_id;
+		Copy(&sockaddr6.sin6_addr, &addr6, sizeof(addr6));
+
+		// ソケット作成
+		s = socket(AF_INET6, SOCK_STREAM, 0);
+		if (s != INVALID_SOCKET)
+		{
+			// 接続
+			if (connect_timeout(s, (struct sockaddr *)&sockaddr6, sizeof(struct sockaddr_in6), timeout, cancel_flag) != 0)
+			{
+				// 接続失敗
+				closesocket(s);
+				s = INVALID_SOCKET;
+			}
+			else
+			{
+				Copy(&current_ip, &ip6, sizeof(IP));
+
+				is_ipv6 = true;
+			}
+		}
+	}
+
+	if (s == INVALID_SOCKET)
+	{
+		// IPv4, IPv6 の両方で接続失敗
+		return NULL;
+	}
+
+	// SOCK の作成
+	sock = NewSock();
+	sock->socket = s;
+	sock->Type = SOCK_TCP;
+	sock->ServerMode = false;
+
+	SetSockPriorityHigh(sock);
+
+	// ホスト名解決
+	if (GetHostName(tmp, sizeof(tmp), &current_ip) == false)
+	{
+		StrCpy(tmp, sizeof(tmp), hostname);
+	}
+
+	//Debug("PTR: %s\n", tmp);
+
+	sock->RemoteHostname = CopyStr(tmp);
+
+//	Debug("new socket: %u\n", s);
+
+	Zero(&ling, sizeof(ling));
+	// 強制切断フラグ
+#ifdef	SO_DONTLINGER
+	setsockopt(sock->socket, SOL_SOCKET, SO_DONTLINGER, (char *)&true_flag, sizeof(bool));
+#else	// SO_DONTLINGER
+	setsockopt(sock->socket, SOL_SOCKET, SO_LINGER, (char *)&false_flag, sizeof(bool));
+#endif	// SO_DONTLINGER
+//	setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (char *)&true_flag, sizeof(bool));
+
+	// TCP オプションの設定
+	setsockopt(sock->socket, IPPROTO_TCP, TCP_NODELAY, (char *)&true_flag, sizeof(bool));
+
+	// タイムアウト値の初期化
+	SetTimeout(sock, TIMEOUT_INFINITE);
+
+	// ソケット情報の取得
+	QuerySocketInformation(sock);
+
+	sock->Connected = true;
+	sock->AsyncMode = false;
+	sock->SecureMode = false;
+	sock->IPv6 = is_ipv6;
+
+	return sock;
+}
+
+// ソケットの送受信バッファサイズを最大にする
+void SetSocketSendRecvBufferSize(int s, UINT size)
+{
+	int value = (int)size;
+	// 引数チェック
+	if (s == INVALID_SOCKET)
+	{
+		return;
+	}
+
+	setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&value, sizeof(int));
+	setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&value, sizeof(int));
+}
+
+// ソケット情報の取得
+void QuerySocketInformation(SOCK *sock)
+{
+	// 引数チェック
+	if (sock == NULL)
+	{
+		return;
+	}
+
+	Lock(sock->lock);
+	{
+		struct sockaddr_in6 sockaddr6;
+		struct in6_addr *addr6;
+		int size;
+
+		if (sock->Type == SOCK_TCP)
+		{
+			// リモートホストの情報を取得
+			size = sizeof(sockaddr6);
+			if (getpeername(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
+			{
+				if (size >= sizeof(struct sockaddr_in6))
+				{
+					sock->RemotePort = (UINT)ntohs(sockaddr6.sin6_port);
+					addr6 = &sockaddr6.sin6_addr;
+					InAddrToIP6(&sock->RemoteIP, addr6);
+					sock->RemoteIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
+				}
+				else
+				{
+					struct sockaddr_in *sockaddr;
+					struct in_addr *addr;
+
+					sockaddr = (struct sockaddr_in *)&sockaddr6;
+					sock->RemotePort = (UINT)ntohs(sockaddr->sin_port);
+					addr = &sockaddr->sin_addr;
+					InAddrToIP(&sock->RemoteIP, addr);
+				}
+			}
+		}
+
+		// ローカルホストの情報を取得
+		size = sizeof(sockaddr6);
+		if (getsockname(sock->socket, (struct sockaddr *)&sockaddr6, (int *)&size) == 0)
+		{
+			if (size >= sizeof(struct sockaddr_in6))
+			{
+				sock->LocalPort = (UINT)ntohs(sockaddr6.sin6_port);
+				addr6 = &sockaddr6.sin6_addr;
+				InAddrToIP6(&sock->LocalIP, addr6);
+				sock->LocalIP.ipv6_scope_id = sockaddr6.sin6_scope_id;
+			}
+			else
+			{
+				struct sockaddr_in *sockaddr;
+				struct in_addr *addr;
+
+				sockaddr = (struct sockaddr_in *)&sockaddr6;
+				sock->LocalPort = (UINT)ntohs(sockaddr->sin_port);
+				addr = &sockaddr->sin_addr;
+				InAddrToIP(&sock->LocalIP, addr);
+			}
+		}
+	}
+	Unlock(sock->lock);
+}
+
+// ソケットの解放
+void ReleaseSock(SOCK *s)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	if (Release(s->ref) == 0)
+	{
+		if (s->ListenMode == false && s->ServerMode)
+		{
+			Print("");
+		}
+		CleanupSock(s);
+	}
+}
+
+// ソケットのクリーンアップ
+void CleanupSock(SOCK *s)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+//	{Debug("CleanupSock: Disconnect() Called: %s %u\n", __FILE__, __LINE__);Disconnect(s);}
+	Disconnect(s);
+
+#ifdef	OS_WIN32
+	Win32FreeAsyncSocket(s);
+#else	// OS_WIN32
+	UnixFreeAsyncSocket(s);
+#endif	// OS_WIN32
+
+	FreeBuf(s->SendBuf);
+	if (s->socket != INVALID_SOCKET)
+	{
+#ifdef	OS_WIN32
+		closesocket(s->socket);
+#else	// OS_WIN32
+		close(s->socket);
+#endif	// OS_WIN32
+	}
+	Free(s->RemoteHostname);
+
+	Free(s->WaitToUseCipher);
+	DeleteLock(s->lock);
+	DeleteLock(s->ssl_lock);
+	DeleteLock(s->disconnect_lock);
+
+	Dec(num_tcp_connections);
+
+	Free(s);
+}
+
+// 新しいソケットの作成
+SOCK *NewSock()
+{
+	SOCK *s = ZeroMallocFast(sizeof(SOCK));
+
+	s->ref = NewRef();
+	s->lock = NewLock();
+	s->SendBuf = NewBuf();
+	s->socket = INVALID_SOCKET;
+	s->ssl_lock = NewLock();
+	s->disconnect_lock = NewLock();
+
+	Inc(num_tcp_connections);
+
+	return s;
+}
+
+// IP を UINT に変換する
+UINT IPToUINT(IP *ip)
+{
+	UCHAR *b;
+	UINT i, value = 0;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return 0;
+	}
+
+	b = (UCHAR *)&value;
+	for (i = 0;i < 4;i++)
+	{
+		b[i] = ip->addr[i];
+	}
+
+	return value;
+}
+
+// UNIT を IP に変換する
+void UINTToIP(IP *ip, UINT value)
+{
+	UCHAR *b;
+	UINT i;
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	ZeroIP4(ip);
+
+	b = (UCHAR *)&value;
+	for (i = 0;i < 4;i++)
+	{
+		ip->addr[i] = b[i];
+	}
+}
+
+// コンピュータのホスト名を取得
+void GetMachineHostName(char *name, UINT size)
+{
+	char tmp[MAX_SIZE];
+	UINT i, len;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	GetMachineName(tmp, sizeof(tmp));
+
+	len = StrLen(tmp);
+	for (i = 0;i < len;i++)
+	{
+		if (tmp[i] == '.')
+		{
+			tmp[i] = 0;
+		}
+	}
+
+	ConvertSafeFileName(name, size, tmp);
+}
+
+// このコンピュータの IP アドレスを取得
+void GetMachineIp(IP *ip)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	Zero(ip, sizeof(IP));
+	SetIP(ip, 127, 0, 0, 1);
+
+	GetMachineName(tmp, sizeof(tmp));
+	GetIP(ip, tmp);
+}
+
+// コンピュータ名を hosts から取得
+bool GetMachineNameFromHosts(char *name, UINT size)
+{
+	bool ret = false;
+	char *s;
+	BUF *b;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	b = ReadDump("/etc/hosts");
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	while (true)
+	{
+		s = CfgReadNextLine(b);
+		if (s == NULL)
+		{
+			break;
+		}
+		else
+		{
+			TOKEN_LIST *t = ParseToken(s, " \t");
+
+			if (t != NULL)
+			{
+				if (t->NumTokens >= 2)
+				{
+					if (StrCmpi(t->Token[0], "127.0.0.1") == 0)
+					{
+						UINT i;
+
+						for (i = 1;i < t->NumTokens;i++)
+						{
+							if (StartWith(t->Token[i], "localhost") == false)
+							{
+								StrCpy(name, size, t->Token[i]);
+								ret = true;
+							}
+						}
+					}
+				}
+			}
+			FreeToken(t);
+		}
+
+		Free(s);
+	}
+
+	FreeBuf(b);
+
+	return ret;
+}
+
+// このコンピュータのコンピュータ名を取得
+void GetMachineName(char *name, UINT size)
+{
+	GetMachineNameEx(name, size, false);
+}
+void GetMachineNameEx(char *name, UINT size, bool no_load_hosts)
+{
+	static char name_cache[MAX_SIZE];
+	static bool name_cached = false;
+	char tmp[MAX_SIZE];
+	char tmp2[MAX_SIZE];
+	IP ip;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	Lock(machine_name_lock);
+	{
+		if (name_cached != false)
+		{
+			StrCpy(name, size, name_cache);
+			Unlock(machine_name_lock);
+			return;
+		}
+		if (gethostname(tmp, MAX_SIZE) != 0)
+		{
+			StrCpy(name, size, "Unknown");
+			Unlock(machine_name_lock);
+			return;
+		}
+		if (GetIP(&ip, tmp) == false)
+		{
+			StrCpy(name, size, tmp);
+			Unlock(machine_name_lock);
+			return;
+		}
+		if (GetHostNameInner(name, size, &ip) == false || StartWith(name, "localhost"))
+		{
+			StrCpy(name, size, tmp);
+		}
+		if (StartWith(name, "localhost"))
+		{
+			if (no_load_hosts == false && OS_IS_UNIX(GetOsInfo()->OsType))
+			{
+				if (GetMachineNameFromHosts(tmp2, sizeof(tmp2)))
+				{
+					StrCpy(name, sizeof(name), tmp2);
+				}
+			}
+		}
+
+		StrCpy(name_cache, sizeof(name_cache), name);
+		name_cached = true;
+	}
+	Unlock(machine_name_lock);
+}
+
+// ホスト名取得スレッド
+void GetHostNameThread(THREAD *t, void *p)
+{
+	IP *ip;
+	char hostname[256];
+	// 引数チェック
+	if (t == NULL || p == NULL)
+	{
+		return;
+	}
+
+	ip = (IP *)p;
+
+	AddWaitThread(t);
+
+	NoticeThreadInit(t);
+
+	if (GetHostNameInner(hostname, sizeof(hostname), ip))
+	{
+		AddHostCache(ip, hostname);
+	}
+
+	Free(ip);
+
+	DelWaitThread(t);
+}
+
+// ホスト名の取得
+bool GetHostName(char *hostname, UINT size, IP *ip)
+{
+	THREAD *t;
+	IP *p_ip;
+	bool ret;
+	// 引数チェック
+	if (hostname == NULL || ip == NULL)
+	{
+		return false;
+	}
+
+	if (GetHostCache(hostname, size, ip))
+	{
+		if (IsEmptyStr(hostname) == false)
+		{
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+	p_ip = ZeroMalloc(sizeof(IP));
+	Copy(p_ip, ip, sizeof(IP));
+
+	t = NewThread(GetHostNameThread, p_ip);
+
+	WaitThreadInit(t);
+
+	WaitThread(t, TIMEOUT_HOSTNAME);
+
+	ReleaseThread(t);
+
+	ret = GetHostCache(hostname, size, ip);
+	if (ret == false)
+	{
+		if (IsIP4(ip))
+		{
+			ret = GetNetBiosName(hostname, size, ip);
+			if (ret)
+			{
+				AddHostCache(ip, hostname);
+			}
+		}
+	}
+	else
+	{
+		if (IsEmptyStr(hostname))
+		{
+			ret = false;
+		}
+	}
+	if (ret == false)
+	{
+		AddHostCache(ip, "");
+		StrCpy(hostname, size, "");
+	}
+
+	return ret;
+}
+
+// DNS 逆引きクエリを行う
+bool GetHostNameInner(char *hostname, UINT size, IP *ip)
+{
+	struct in_addr addr;
+	struct sockaddr_in sa;
+	char tmp[MAX_SIZE];
+	char ip_str[64];
+	// 引数チェック
+	if (hostname == NULL || ip == NULL)
+	{
+		return false;
+	}
+
+	if (IsIP6(ip))
+	{
+		return GetHostNameInner6(hostname, size, ip);
+	}
+
+	// 逆引き
+	IPToInAddr(&addr, ip);
+	Zero(&sa, sizeof(sa));
+	sa.sin_family = AF_INET;
+
+#if	defined(UNIX_BSD) || defined(UNIX_MACOS)
+	sa.sin_len = INET_ADDRSTRLEN;
+#endif	// UNIX_BSD || UNIX_MACOS
+
+	Copy(&sa.sin_addr, &addr, sizeof(struct in_addr));
+	sa.sin_port = 0;
+
+	if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), tmp, sizeof(tmp), NULL, 0, 0) != 0)
+	{
+		return false;
+	}
+
+	IPToStr(ip_str, sizeof(ip_str), ip);
+
+	if (StrCmpi(tmp, ip_str) == 0)
+	{
+		return false;
+	}
+
+	if (IsEmptyStr(tmp))
+	{
+		return false;
+	}
+
+	StrCpy(hostname, size, tmp);
+
+	return true;
+}
+bool GetHostNameInner6(char *hostname, UINT size, IP *ip)
+{
+	struct in6_addr addr;
+	struct sockaddr_in6 sa;
+	char tmp[MAX_SIZE];
+	char ip_str[256];
+	// 引数チェック
+	if (hostname == NULL || ip == NULL)
+	{
+		return false;
+	}
+
+	// 逆引き
+	IPToInAddr6(&addr, ip);
+	Zero(&sa, sizeof(sa));
+	sa.sin6_family = AF_INET6;
+
+#if	defined(UNIX_BSD) || defined(UNIX_MACOS)
+	sa.sin6_len = INET6_ADDRSTRLEN;
+#endif	// UNIX_BSD || UNIX_MACOS
+
+	Copy(&sa.sin6_addr, &addr, sizeof(struct in6_addr));
+	sa.sin6_port = 0;
+
+	if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), tmp, sizeof(tmp), NULL, 0, 0) != 0)
+	{
+		return false;
+	}
+
+	IPToStr(ip_str, sizeof(ip_str), ip);
+
+	if (StrCmpi(tmp, ip_str) == 0)
+	{
+		return false;
+	}
+
+	if (IsEmptyStr(tmp))
+	{
+		return false;
+	}
+
+	StrCpy(hostname, size, tmp);
+
+	return true;
+}
+
+#define	NUM_NBT_QUERYS_SEND			3
+
+// IP アドレスからそのマシンの NetBIOS 名を取得する
+bool GetNetBiosName(char *name, UINT size, IP *ip)
+{
+	SOCK *s;
+	UINT i, j;
+	bool flag = false;
+	bool ok = false;
+	NBTREQUEST req;
+	UCHAR buf[1024];
+	USHORT tran_id[NUM_NBT_QUERYS_SEND];
+	UINT64 timeout_tick;
+	// 引数チェック
+	if (name == NULL || ip == NULL)
+	{
+		return false;
+	}
+
+	IPToStr(name, size, ip);
+
+	for (i = 0;i < NUM_NBT_QUERYS_SEND;i++)
+	{
+		tran_id[i] = Rand16();
+	}
+
+	s = NewUDP(0);
+	if (s == NULL)
+	{
+		return false;
+	}
+
+	for (j = 0;j < NUM_NBT_QUERYS_SEND;j++)
+	{
+		Zero(&req, sizeof(req));
+		req.TransactionId = Endian16(tran_id[j]);
+		req.NumQuestions = Endian16(1);
+		req.Query[0] = 0x20;
+		req.Query[1] = 0x43;
+		req.Query[2] = 0x4b;
+		for (i = 3;i <= 32;i++)
+		{
+			req.Query[i] = 0x41;
+		}
+		req.Query[35] = 0x21;
+		req.Query[37] = 0x01;
+
+		if (SendTo(s, ip, 137, &req, sizeof(req)) == 0)
+		{
+			ReleaseSock(s);
+			return false;
+		}
+	}
+
+	timeout_tick = Tick() + (UINT64)TIMEOUT_NETBIOS_HOSTNAME;
+
+	while (1)
+	{
+		UINT ret;
+		IP src_ip;
+		UINT src_port;
+		SOCKSET set;
+		if (Tick() >= timeout_tick)
+		{
+			break;
+		}
+		InitSockSet(&set);
+		AddSockSet(&set, s);
+		Select(&set, 100, NULL, NULL);
+
+		if (flag == false)
+		{
+			flag = true;
+		}
+		else
+		{
+			SleepThread(10);
+		}
+
+		ret = RecvFrom(s, &src_ip, &src_port, buf, sizeof(buf));
+
+		if (ret == SOCK_LATER)
+		{
+			continue;
+		}
+		else if (ret == 0)
+		{
+			break;
+		}
+		else
+		{
+			if (ret >= sizeof(NBTRESPONSE))
+			{
+				NBTRESPONSE *r = (NBTRESPONSE *)buf;
+				bool b = false;
+				UINT i;
+				USHORT id = Endian16(r->TransactionId);
+				for (i = 0;i < NUM_NBT_QUERYS_SEND;i++)
+				{
+					if (id == tran_id[i])
+					{
+						b = true;
+						break;
+					}
+				}
+				if (b)
+				{
+					if (r->Flags != 0 && r->NumQuestions == 0 && r->AnswerRRs >= 1)
+					{
+						if (r->Response[0] == 0x20 && r->Response[1] == 0x43 &&
+							r->Response[2] == 0x4b)
+						{
+							if (r->Response[34] == 0x00 && r->Response[35] == 0x21 &&
+								r->Response[36] == 0x00 && r->Response[37] == 0x01)
+							{
+								char *a = (char *)(&r->Response[45]);
+								if (StrCheckLen(a, 15))
+								{
+									if (IsEmptyStr(a) == false)
+									{
+										StrCpy(name, size, a);
+										Trim(name);
+										ok = true;
+									}
+									else
+									{
+										ok = false;
+										break;
+									}
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	ReleaseSock(s);
+	return ok;
+}
+
+// IP アドレスを設定する
+void SetIP(IP *ip, UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4)
+{
+	// 引数チェック
+	if (ip == NULL)
+	{
+		return;
+	}
+
+	Zero(ip, sizeof(IP));
+	ip->addr[0] = a1;
+	ip->addr[1] = a2;
+	ip->addr[2] = a3;
+	ip->addr[3] = a4;
+}
+
+// DNS 正引きを行って結果を v4 と v6 のどちらかで得る (両方の場合は IPv4 優先)
+bool GetIP46Any4(IP *ip, char *hostname)
+{
+	IP ip4, ip6;
+	bool b = false;
+	// 引数チェック
+	if (ip == NULL || hostname == NULL)
+	{
+		return false;
+	}
+
+	if (GetIP46(&ip4, &ip6, hostname) == false)
+	{
+		return false;
+	}
+
+	if (IsZeroIp(&ip6) == false)
+	{
+		Copy(ip, &ip6, sizeof(IP));
+
+		b = true;
+	}
+
+	if (IsZeroIp(&ip4) == false)
+	{
+		Copy(ip, &ip4, sizeof(IP));
+
+		b = true;
+	}
+
+	return b;
+}
+
+// DNS 正引きを行って結果を v4 と v6 のどちらかで得る (両方の場合は IPv6 優先)
+bool GetIP46Any6(IP *ip, char *hostname)
+{
+	IP ip4, ip6;
+	bool b = false;
+	// 引数チェック
+	if (ip == NULL || hostname == NULL)
+	{
+		return false;
+	}
+
+	if (GetIP46(&ip4, &ip6, hostname) == false)
+	{
+		return false;
+	}
+
+	if (IsZeroIp(&ip4) == false)
+	{
+		Copy(ip, &ip4, sizeof(IP));
+
+		b = true;
+	}
+
+	if (IsZeroIp(&ip6) == false)
+	{
+		Copy(ip, &ip6, sizeof(IP));
+
+		b = true;
+	}
+
+	return b;
+}
+
+// DNS 正引きを行って結果を v4 と v6 の両方で得る
+bool GetIP46(IP *ip4, IP *ip6, char *hostname)
+{
+	return GetIP46Ex(ip4, ip6, hostname, 0, NULL);
+}
+bool GetIP46Ex(IP *ip4, IP *ip6, char *hostname, UINT timeout, bool *cancel)
+{
+	IP a, b;
+	bool ok_a, ok_b;
+	// 引数チェック
+	if (ip4 == NULL || ip6 == NULL || hostname == NULL)
+	{
+		return false;
+	}
+
+	ZeroIP4(ip4);
+	ZeroIP6(ip6);
+
+	ok_a = ok_b = false;
+
+	if (GetIP6Ex(&a, hostname, timeout, cancel))
+	{
+		ok_a = true;
+	}
+
+	if (GetIP4Ex(&b, hostname, timeout, cancel))
+	{
+		ok_b = true;
+	}
+
+	if (ok_a)
+	{
+		if (IsIP4(&a))
+		{
+			Copy(ip4, &a, sizeof(IP));
+		}
+	}
+	if (ok_b)
+	{
+		if (IsIP4(&b))
+		{
+			Copy(ip4, &b, sizeof(IP));
+		}
+
+		if (IsIP6(&b))
+		{
+			Copy(ip6, &b, sizeof(IP));
+		}
+	}
+	if (ok_a)
+	{
+		if (IsIP6(&a))
+		{
+			Copy(ip6, &a, sizeof(IP));
+		}
+	}
+
+	if (IsZeroIp(ip4) && IsZeroIp(ip6))
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// GetIP 用スレッドのパラメータのクリーンアップ
+void CleanupGetIPThreadParam(GETIP_THREAD_PARAM *p)
+{
+	// 引数チェック
+	if (p == NULL)
+	{
+		return;
+	}
+
+	Free(p);
+}
+
+// GetIP 用スレッドのパラメータの解放
+void ReleaseGetIPThreadParam(GETIP_THREAD_PARAM *p)
+{
+	// 引数チェック
+	if (p == NULL)
+	{
+		return;
+	}
+
+	if (Release(p->Ref) == 0)
+	{
+		CleanupGetIPThreadParam(p);
+	}
+}
+
+// DNS 正引きクエリ (タイムアウト付き) を行うスレッド
+void GetIP4Ex6ExThread(THREAD *t, void *param)
+{
+	GETIP_THREAD_PARAM *p;
+	// 引数チェック
+	if (t == NULL || param == NULL)
+	{
+		return;
+	}
+
+	p = (GETIP_THREAD_PARAM *)param;
+
+	AddRef(p->Ref);
+
+	NoticeThreadInit(t);
+
+	AddWaitThread(t);
+
+	// 解決の実行
+	if (p->IPv6 == false)
+	{
+		// IPv4
+		p->Ok = GetIP4Inner(&p->Ip, p->HostName);
+	}
+	else
+	{
+		// IPv6
+		p->Ok = GetIP6Inner(&p->Ip, p->HostName);
+	}
+
+	ReleaseGetIPThreadParam(p);
+
+	DelWaitThread(t);
+}
+
+// DNS 正引きクエリ (タイムアウト付き) を行う
+bool GetIP4Ex6Ex(IP *ip, char *hostname, UINT timeout, bool ipv6, bool *cancel)
+{
+	GETIP_THREAD_PARAM *p;
+	THREAD *t;
+	bool ret = false;
+	UINT64 start_tick = 0;
+	UINT64 end_tick = 0;
+	// 引数チェック
+	if (ip == NULL || hostname == NULL)
+	{
+		return false;
+	}
+	if (timeout == 0)
+	{
+		timeout = TIMEOUT_GETIP;
+	}
+
+	p = ZeroMalloc(sizeof(GETIP_THREAD_PARAM));
+	p->Ref = NewRef();
+	StrCpy(p->HostName, sizeof(p->HostName), hostname);
+	p->IPv6 = ipv6;
+	p->Timeout = timeout;
+	p->Ok = false;
+
+	t = NewThread(GetIP4Ex6ExThread, p);
+	WaitThreadInit(t);
+
+	if (cancel == NULL)
+	{
+		WaitThread(t, timeout);
+	}
+	else
+	{
+		start_tick = Tick64();
+		end_tick = start_tick + (UINT64)timeout;
+
+		while (true)
+		{
+			UINT64 now = Tick64();
+			UINT64 remain;
+			UINT remain32;
+
+			if (*cancel)
+			{
+				break;
+			}
+
+			if (now >= end_tick)
+			{
+				break;
+			}
+
+			remain = end_tick - now;
+			remain32 = MIN((UINT)remain, 100);
+
+			if (WaitThread(t, remain32))
+			{
+				break;
+			}
+		}
+	}
+
+	ReleaseThread(t);
+
+	if (p->Ok)
+	{
+		ret = true;
+		Copy(ip, &p->Ip, sizeof(IP));
+	}
+
+	ReleaseGetIPThreadParam(p);
+
+	return ret;
+}
+bool GetIP4Ex(IP *ip, char *hostname, UINT timeout, bool *cancel)
+{
+	return GetIP4Ex6Ex(ip, hostname, timeout, false, cancel);
+}
+bool GetIP6Ex(IP *ip, char *hostname, UINT timeout, bool *cancel)
+{
+	return GetIP4Ex6Ex(ip, hostname, timeout, true, cancel);
+}
+bool GetIP4(IP *ip, char *hostname)
+{
+	return GetIP4Ex(ip, hostname, 0, NULL);
+}
+bool GetIP6(IP *ip, char *hostname)
+{
+	return GetIP6Ex(ip, hostname, 0, NULL);
+}
+
+// DNS 正引きクエリを行う
+bool GetIP(IP *ip, char *hostname)
+{
+	return GetIPEx(ip, hostname, false);
+}
+bool GetIPEx(IP *ip, char *hostname, bool ipv6)
+{
+	if (ipv6 == false)
+	{
+		return GetIP4(ip, hostname);
+	}
+	else
+	{
+		return GetIP6(ip, hostname);
+	}
+}
+bool GetIP6Inner(IP *ip, char *hostname)
+{
+	struct sockaddr_in6 in;
+	struct in6_addr addr;
+	struct addrinfo hint;
+	struct addrinfo *info;
+	// 引数チェック
+	if (ip == NULL || hostname == NULL)
+	{
+		return false;
+	}
+
+	if (IsEmptyStr(hostname))
+	{
+		return false;
+	}
+
+	if (StrCmpi(hostname, "localhost") == 0)
+	{
+		GetLocalHostIP6(ip);
+		return true;
+	}
+
+	if (StrToIP6(ip, hostname) == false && StrToIP(ip, hostname) == false)
+	{
+		// 正引き
+		Zero(&hint, sizeof(hint));
+		hint.ai_family = AF_INET6;
+		hint.ai_socktype = SOCK_STREAM;
+		hint.ai_protocol = IPPROTO_TCP;
+		info = NULL;
+
+		if (getaddrinfo(hostname, NULL, &hint, &info) != 0 ||
+			info->ai_family != AF_INET6)
+		{
+			if (info)
+			{
+				freeaddrinfo(info);
+			}
+			return QueryDnsCacheEx(ip, hostname, true);
+		}
+		// 正引き成功
+		Copy(&in, info->ai_addr, sizeof(struct sockaddr_in6));
+		freeaddrinfo(info);
+
+		Copy(&addr, &in.sin6_addr, sizeof(addr));
+		InAddrToIP6(ip, &addr);
+	}
+
+	// キャッシュ保存
+	NewDnsCache(hostname, ip);
+
+	return true;
+}
+bool GetIP4Inner(IP *ip, char *hostname)
+{
+	struct sockaddr_in in;
+	struct in_addr addr;
+	struct addrinfo hint;
+	struct addrinfo *info;
+	// 引数チェック
+	if (ip == NULL || hostname == NULL)
+	{
+		return false;
+	}
+
+	if (IsEmptyStr(hostname))
+	{
+		return false;
+	}
+
+	if (StrCmpi(hostname, "localhost") == 0)
+	{
+		SetIP(ip, 127, 0, 0, 1);
+		return true;
+	}
+
+	if (StrToIP6(ip, hostname) == false && StrToIP(ip, hostname) == false)
+	{
+		// 正引き
+		Zero(&hint, sizeof(hint));
+		hint.ai_family = AF_INET;
+		hint.ai_socktype = SOCK_STREAM;
+		hint.ai_protocol = IPPROTO_TCP;
+		info = NULL;
+
+		if (getaddrinfo(hostname, NULL, &hint, &info) != 0 ||
+			info->ai_family != AF_INET)
+		{
+			if (info)
+			{
+				freeaddrinfo(info);
+			}
+			return QueryDnsCache(ip, hostname);
+		}
+		// 正引き成功
+		Copy(&in, info->ai_addr, sizeof(struct sockaddr_in));
+		freeaddrinfo(info);
+		Copy(&addr, &in.sin_addr, sizeof(addr));
+		InAddrToIP(ip, &addr);
+	}
+
+	// キャッシュ保存
+	NewDnsCache(hostname, ip);
+
+	return true;
+}
+
+// DNS キャッシュを検索する
+bool QueryDnsCache(IP *ip, char *hostname)
+{
+	return QueryDnsCacheEx(ip, hostname, false);
+}
+bool QueryDnsCacheEx(IP *ip, char *hostname, bool ipv6)
+{
+	DNSCACHE *c;
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (ip == NULL || hostname == NULL)
+	{
+		return false;
+	}
+
+	GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
+
+	c = FindDnsCache(tmp);
+	if (c == NULL)
+	{
+		return false;
+	}
+
+	Copy(ip, &c->IpAddress, sizeof(IP));
+
+	return true;
+}
+
+// IP を文字列に変換
+void IPToUniStr(wchar_t *str, UINT size, IP *ip)
+{
+	char tmp[128];
+
+	IPToStr(tmp, sizeof(tmp), ip);
+	StrToUni(str, size, tmp);
+}
+
+// IP を文字列に変換 (32bit UINT)
+void IPToUniStr32(wchar_t *str, UINT size, UINT ip)
+{
+	char tmp[128];
+
+	IPToStr32(tmp, sizeof(tmp), ip);
+	StrToUni(str, size, tmp);
+}
+
+// IP を文字列に変換 (128bit byte array)
+void IPToStr128(char *str, UINT size, UCHAR *ip_bytes)
+{
+	IP ip_st;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	SetIP6(&ip_st, ip_bytes);
+	IPToStr(str, size, &ip_st);
+}
+
+// IP を文字列に変換 (32bit UINT)
+void IPToStr32(char *str, UINT size, UINT ip)
+{
+	IP ip_st;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	UINTToIP(&ip_st, ip);
+	IPToStr(str, size, &ip_st);
+}
+
+// IPv4 または IPv6 を文字列に変換
+void IPToStr4or6(char *str, UINT size, UINT ip_4_uint, UCHAR *ip_6_bytes)
+{
+	IP ip4;
+	IP ip6;
+	IP ip;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	Zero(&ip, sizeof(ip));
+
+	UINTToIP(&ip4, ip_4_uint);
+	SetIP6(&ip6, ip_6_bytes);
+
+	if (IsIP6(&ip4) || (IsZeroIp(&ip4) && (IsZeroIp(&ip6) == false)))
+	{
+		Copy(&ip, &ip6, sizeof(IP));
+	}
+	else
+	{
+		Copy(&ip, &ip4, sizeof(IP));
+	}
+
+	IPToStr(str, size, &ip);
+}
+
+// IP を文字列に変換
+void IPToStr(char *str, UINT size, IP *ip)
+{
+	// 引数チェック
+	if (str == NULL || ip == NULL)
+	{
+		return;
+	}
+
+	if (IsIP6(ip))
+	{
+		IPToStr6(str, size, ip);
+	}
+	else
+	{
+		IPToStr4(str, size, ip);
+	}
+}
+
+// IPv4 を文字列に変換
+void IPToStr4(char *str, UINT size, IP *ip)
+{
+	// 引数チェック
+	if (str == NULL || ip == NULL)
+	{
+		return;
+	}
+
+	// 変換
+	snprintf(str, size != 0 ? size : 64, "%u.%u.%u.%u", ip->addr[0], ip->addr[1], ip->addr[2], ip->addr[3]);
+}
+
+// 文字列を IP に変換
+bool StrToIP(IP *ip, char *str)
+{
+	TOKEN_LIST *token;
+	char *tmp;
+	UINT i;
+	// 引数チェック
+	if (ip == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	if (StrToIP6(ip, str))
+	{
+		return true;
+	}
+
+	Zero(ip, sizeof(IP));
+
+	tmp = CopyStr(str);
+	Trim(tmp);
+	token = ParseToken(tmp, ".");
+	Free(tmp);
+
+	if (token->NumTokens != 4)
+	{
+		FreeToken(token);
+		return false;
+	}
+	for (i = 0;i < 4;i++)
+	{
+		char *s = token->Token[i];
+		if (s[0] < '0' || s[0] > '9' ||
+			(ToInt(s) >= 256))
+		{
+			FreeToken(token);
+			return false;
+		}
+	}
+	Zero(ip, sizeof(IP));
+	for (i = 0;i < 4;i++)
+	{
+		ip->addr[i] = (UCHAR)ToInt(token->Token[i]);
+	}
+
+	FreeToken(token);
+
+	return true;
+}
+UINT StrToIP32(char *str)
+{
+	IP ip;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	if (StrToIP(&ip, str) == false)
+	{
+		return 0;
+	}
+
+	return IPToUINT(&ip);
+}
+bool UniStrToIP(IP *ip, wchar_t *str)
+{
+	char *tmp;
+	bool ret;
+
+	tmp = CopyUniToStr(str);
+	ret = StrToIP(ip, tmp);
+	Free(tmp);
+
+	return ret;
+}
+UINT UniStrToIP32(wchar_t *str)
+{
+	UINT ret;
+	char *tmp;
+
+	tmp = CopyUniToStr(str);
+	ret = StrToIP32(tmp);
+	Free(tmp);
+
+	return ret;
+}
+
+// IP を in_addr に変換
+void IPToInAddr(struct in_addr *addr, IP *ip)
+{
+	UINT i;
+	// 引数チェック
+	if (addr == NULL || ip == NULL)
+	{
+		return;
+	}
+
+	Zero(addr, sizeof(struct in_addr));
+
+	if (IsIP6(ip) == false)
+	{
+		for (i = 0;i < 4;i++)
+		{
+			((UCHAR *)addr)[i] = ip->addr[i];
+		}
+	}
+}
+
+// IP を in6_addr に変換
+void IPToInAddr6(struct in6_addr *addr, IP *ip)
+{
+	UINT i;
+	// 引数チェック
+	if (addr == NULL || ip == NULL)
+	{
+		return;
+	}
+
+	Zero(addr, sizeof(struct in_addr));
+
+	if (IsIP6(ip))
+	{
+		for (i = 0;i < 16;i++)
+		{
+			((UCHAR *)addr)[i] = ip->ipv6_addr[i];
+		}
+	}
+}
+
+// in_addr を IP に変換
+void InAddrToIP(IP *ip, struct in_addr *addr)
+{
+	UINT i;
+	// 引数チェック
+	if (ip == NULL || addr == NULL)
+	{
+		return;
+	}
+
+	Zero(ip, sizeof(IP));
+
+	for (i = 0;i < 4;i++)
+	{
+		ip->addr[i] = ((UCHAR *)addr)[i];
+	}
+}
+
+// in6_addr を IP に変換
+void InAddrToIP6(IP *ip, struct in6_addr *addr)
+{
+	UINT i;
+	// 引数チェック
+	if (ip == NULL || addr == NULL)
+	{
+		return;
+	}
+
+	ZeroIP6(ip);
+	for (i = 0;i < 16;i++)
+	{
+		ip->ipv6_addr[i] = ((UCHAR *)addr)[i];
+	}
+}
+
+// DNS キャッシュの検索
+DNSCACHE *FindDnsCache(char *hostname)
+{
+	return FindDnsCacheEx(hostname, false);
+}
+DNSCACHE *FindDnsCacheEx(char *hostname, bool ipv6)
+{
+	DNSCACHE *c;
+	char tmp[MAX_SIZE];
+	if (hostname == NULL)
+	{
+		return NULL;
+	}
+
+	GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
+
+	LockDnsCache();
+	{
+		DNSCACHE t;
+		t.HostName = tmp;
+		c = Search(DnsCache, &t);
+	}
+	UnlockDnsCache();
+
+	return c;
+}
+
+// DNS キャッシュ用の IPv4 / IPv6 キー名を生成
+void GenDnsCacheKeyName(char *dst, UINT size, char *src, bool ipv6)
+{
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return;
+	}
+
+	if (ipv6 == false)
+	{
+		StrCpy(dst, size, src);
+	}
+	else
+	{
+		Format(dst, size, "%s@ipv6", src);
+	}
+}
+
+// 新しい DNS キャッシュの登録
+void NewDnsCache(char *hostname, IP *ip)
+{
+	NewDnsCacheEx(hostname, ip, IsIP6(ip));
+}
+void NewDnsCacheEx(char *hostname, IP *ip, bool ipv6)
+{
+	DNSCACHE *c;
+	char tmp[MAX_PATH];
+	// 引数チェック
+	if (hostname == NULL || ip == NULL)
+	{
+		return;
+	}
+
+	if (IsNetworkNameCacheEnabled() == false)
+	{
+		return;
+	}
+
+	GenDnsCacheKeyName(tmp, sizeof(tmp), hostname, ipv6);
+
+	LockDnsCache();
+	{
+		DNSCACHE t;
+
+		// まず hostname に該当するものがあるかどうか検索してみる
+		t.HostName = tmp;
+		c = Search(DnsCache, &t);
+
+		if (c == NULL)
+		{
+			// 新規登録
+			c = ZeroMalloc(sizeof(DNSCACHE));
+			c->HostName = CopyStr(tmp);
+
+			Copy(&c->IpAddress, ip, sizeof(IP));
+
+			Add(DnsCache, c);
+		}
+		else
+		{
+			// 更新
+			Copy(&c->IpAddress, ip, sizeof(IP));
+		}
+	}
+	UnlockDnsCache();
+}
+
+// DNS キャッシュの名前比較
+int CompareDnsCache(void *p1, void *p2)
+{
+	DNSCACHE *c1, *c2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	c1 = *(DNSCACHE **)p1;
+	c2 = *(DNSCACHE **)p2;
+	if (c1 == NULL || c2 == NULL)
+	{
+		return 0;
+	}
+
+	return StrCmpi(c1->HostName, c2->HostName);
+}
+
+// DNS キャッシュの初期化
+void InitDnsCache()
+{
+	// リスト作成
+	DnsCache = NewList(CompareDnsCache);
+}
+
+// DNS キャッシュの解放
+void FreeDnsCache()
+{
+	LockDnsCache();
+	{
+		DNSCACHE *c;
+		UINT i;
+		for (i = 0;i < LIST_NUM(DnsCache);i++)
+		{
+			// エントリのメモリ解放
+			c = LIST_DATA(DnsCache, i);
+			Free(c->HostName);
+			Free(c);
+		}
+	}
+	UnlockDnsCache();
+
+	// リスト解放
+	ReleaseList(DnsCache);
+	DnsCache = NULL;
+}
+
+// DNS キャッシュのロック
+void LockDnsCache()
+{
+	LockList(DnsCache);
+}
+
+// DNS キャッシュのロック解除
+void UnlockDnsCache()
+{
+	UnlockList(DnsCache);
+}
+
+// ネットワーク通信モジュールの初期化
+void InitNetwork()
+{
+	num_tcp_connections = NewCounter();
+
+	// クライアントリストの初期化
+	InitIpClientList();
+
+	// スレッド関係の初期化
+	InitWaitThread();
+
+	// ホスト名キャッシュの初期化
+	InitHostCache();
+
+#ifdef	OS_WIN32
+	// ソケットライブラリの初期化
+	Win32InitSocketLibrary();
+#else
+	UnixInitSocketLibrary();
+#endif	// OS_WIN32
+
+	// DNS キャッシュの初期化
+	InitDnsCache();
+
+	// OpenSSL の初期化
+	ssl_ctx = SSL_CTX_new(SSLv23_method());
+
+	// ロック初期化
+	machine_name_lock = NewLock();
+	disconnect_function_lock = NewLock();
+	aho = NewLock();
+	socket_library_lock = NewLock();
+	ssl_connect_lock = NewLock();
+//	ssl_accept_lock = NewLock();
+	dns_lock = NewLock();
+	unix_dns_server_addr_lock = NewLock();
+	Zero(&unix_dns_server, sizeof(unix_dns_server));
+
+	cipher_list_token = ParseToken(cipher_list, " ");
+
+	disable_cache = false;
+}
+
+// ネットワーク名キャッシュの有効化
+void EnableNetworkNameCache()
+{
+	disable_cache = false;
+}
+
+// ネットワーク名キャッシュの無効化
+void DisableNetworkNameCache()
+{
+	disable_cache = true;
+}
+
+// ネットワーク名キャッシュが有効かどうか取得
+bool IsNetworkNameCacheEnabled()
+{
+	return !disable_cache;
+}
+
+// 暗号化アルゴリズムリストを取得
+TOKEN_LIST *GetCipherList()
+{
+	return cipher_list_token;
+}
+
+// TCP コネクション数カウンタを取得
+COUNTER *GetNumTcpConnectionsCounter()
+{
+	return num_tcp_connections;
+}
+
+// ネットワーク通信モジュールの解放
+void FreeNetwork()
+{
+	FreeToken(cipher_list_token);
+	cipher_list_token = NULL;
+
+	Zero(&unix_dns_server, sizeof(unix_dns_server));
+
+	// ロック解放
+	DeleteLock(unix_dns_server_addr_lock);
+	DeleteLock(dns_lock);
+	DeleteLock(ssl_accept_lock);
+	DeleteLock(machine_name_lock);
+	DeleteLock(disconnect_function_lock);
+	DeleteLock(aho);
+	DeleteLock(socket_library_lock);
+	DeleteLock(ssl_connect_lock);
+	machine_name_lock = NULL;
+	ssl_accept_lock = machine_name_lock = disconnect_function_lock =
+		aho = socket_library_lock = ssl_connect_lock = NULL;
+
+	// OpenSSL の解放
+	SSL_CTX_free(ssl_ctx);
+	ssl_ctx = NULL;
+
+	// スレッド関係の解放
+	FreeWaitThread();
+
+	// DNS キャッシュの解放
+	FreeDnsCache();
+
+	// ホスト名キャッシュの解放
+	FreeHostCache();
+
+#ifdef	OS_WIN32
+	// ソケットライブラリの解放
+	Win32FreeSocketLibrary();
+#else
+	UnixFreeSocketLibrary();
+#endif	// OS_WIN32
+
+	DeleteCounter(num_tcp_connections);
+	num_tcp_connections = NULL;
+
+	// クライアントリストの解放
+	FreeIpClientList();
+}
+
+// ソケットリストにソケットを追加する
+void AddSockList(SOCKLIST *sl, SOCK *s)
+{
+	// 引数チェック
+	if (sl == NULL || s == NULL)
+	{
+		return;
+	}
+
+	LockList(sl->SockList);
+	{
+		if (IsInList(sl->SockList, s) == false)
+		{
+			AddRef(s->ref);
+
+			Insert(sl->SockList, s);
+		}
+	}
+	UnlockList(sl->SockList);
+}
+
+// ソケットリストからソケットを削除する
+void DelSockList(SOCKLIST *sl, SOCK *s)
+{
+	// 引数チェック
+	if (sl == NULL || s == NULL)
+	{
+		return;
+	}
+
+	LockList(sl->SockList);
+	{
+		if (Delete(sl->SockList, s))
+		{
+			ReleaseSock(s);
+		}
+	}
+	UnlockList(sl->SockList);
+}
+
+// ソケットリストのソケットをすべて停止させて削除する
+void StopSockList(SOCKLIST *sl)
+{
+	SOCK **ss;
+	UINT num, i;
+	// 引数チェック
+	if (sl == NULL)
+	{
+		return;
+	}
+
+	LockList(sl->SockList);
+	{
+		num = LIST_NUM(sl->SockList);
+		ss = ToArray(sl->SockList);
+
+		DeleteAll(sl->SockList);
+	}
+	UnlockList(sl->SockList);
+
+	for (i = 0;i < num;i++)
+	{
+		SOCK *s = ss[i];
+
+		Disconnect(s);
+		ReleaseSock(s);
+	}
+
+	Free(ss);
+}
+
+// ソケットリストの削除
+void FreeSockList(SOCKLIST *sl)
+{
+	// 引数チェック
+	if (sl == NULL)
+	{
+		return;
+	}
+
+	StopSockList(sl);
+
+	ReleaseList(sl->SockList);
+
+	Free(sl);
+}
+
+// ソケットリストの作成
+SOCKLIST *NewSockList()
+{
+	SOCKLIST *sl = ZeroMallocFast(sizeof(SOCKLIST));
+
+	sl->SockList = NewList(NULL);
+
+	return sl;
+}
+
+// Solarisでのソケットのタイムアウト用スレッド
+void SocketTimeoutThread(THREAD *t, void *param)
+{
+	SOCKET_TIMEOUT_PARAM *ttparam;
+	ttparam = (SOCKET_TIMEOUT_PARAM *)param;
+
+	// タイムアウト時間だけ待つ
+	Select(NULL, ttparam->sock->TimeOut, ttparam->cancel, NULL);
+
+	// ブロック中ならディスコネクトする
+	if(! ttparam->unblocked)
+	{
+//		Debug("Socket timeouted\n");
+		closesocket(ttparam->sock->socket);
+	}
+	else
+	{
+//		Debug("Socket timeout cancelled\n");
+	}
+}
+
+// タイムアウト用スレッドの初期化と開始
+SOCKET_TIMEOUT_PARAM *NewSocketTimeout(SOCK *sock)
+{
+	SOCKET_TIMEOUT_PARAM *ttp;
+	if(! sock->AsyncMode && sock->TimeOut != TIMEOUT_INFINITE)
+	{
+//		Debug("NewSockTimeout(%u)\n",sock->TimeOut);
+
+		ttp = (SOCKET_TIMEOUT_PARAM*)Malloc(sizeof(SOCKET_TIMEOUT_PARAM));
+
+		// タイムアウトスレッド用のパラメータをセット
+		ttp->cancel = NewCancel();
+		ttp->sock = sock;
+		ttp->unblocked = false;
+		ttp->thread = NewThread(SocketTimeoutThread, ttp);
+		return ttp;
+	}
+	return NULL;
+}
+
+// タイムアウト用スレッドの停止と開放
+void FreeSocketTimeout(SOCKET_TIMEOUT_PARAM *ttp)
+{
+	if(ttp == NULL)
+	{
+		return;
+	}
+
+	ttp->unblocked = true;
+	Cancel(ttp->cancel);
+	WaitThread(ttp->thread, INFINITE);
+	ReleaseCancel(ttp->cancel);
+	ReleaseThread(ttp->thread);
+	Free(ttp);
+//	Debug("FreeSocketTimeout succeed\n");
+	return;
+}
+
+// IP アドレスとサブネット マスクのパース
+bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask)
+{
+	// 引数チェック
+	if (src == NULL || ip == NULL || mask == NULL)
+	{
+		return false;
+	}
+
+	if (ParseIpAndMask46(src, ip, mask) == false)
+	{
+		return false;
+	}
+
+	if (IsIP4(ip))
+	{
+		return IsSubnetMask4(mask);
+	}
+	else
+	{
+		return IsSubnetMask6(mask);
+	}
+}
+bool ParseIpAndSubnetMask6(char *src, IP *ip, IP *mask)
+{
+	if (ParseIpAndSubnetMask46(src, ip, mask) == false)
+	{
+		return false;
+	}
+
+	if (IsIP6(ip) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask)
+{
+	IP ip2, mask2;
+	// 引数チェック
+	if (src == NULL)
+	{
+		return false;
+	}
+
+	if (ParseIpAndSubnetMask46(src, &ip2, &mask2) == false)
+	{
+		return false;
+	}
+
+	if (IsIP4(&ip2) == false)
+	{
+		return false;
+	}
+
+	if (ip != NULL)
+	{
+		*ip = IPToUINT(&ip2);
+	}
+
+	if (mask != NULL)
+	{
+		*mask = IPToUINT(&mask2);
+	}
+
+	return true;
+}
+
+
+// IP アドレスとマスクのパース
+bool ParseIpAndMask46(char *src, IP *ip, IP *mask)
+{
+	TOKEN_LIST *t;
+	char *ipstr;
+	char *subnetstr;
+	bool ret = false;
+	IP ip2;
+	IP mask2;
+	// 引数チェック
+	if (src == NULL || ip == NULL || mask == NULL)
+	{
+		return false;
+	}
+
+	Zero(&ip2, sizeof(IP));
+	Zero(&mask2, sizeof(IP));
+
+	t = ParseToken(src, "/");
+	if (t->NumTokens != 2)
+	{
+		FreeToken(t);
+		return false;
+	}
+
+	ipstr = t->Token[0];
+	subnetstr = t->Token[1];
+	Trim(ipstr);
+	Trim(subnetstr);
+
+	if (StrToIP(&ip2, ipstr))
+	{
+		if (StrToIP(&mask2, subnetstr))
+		{
+			// IP アドレス部とマスク部が同一の種類かどうか比較する
+			if (IsIP6(&ip2) && IsIP6(&mask2))
+			{
+				// 両方とも IPv6
+				ret = true;
+				Copy(ip, &ip2, sizeof(IP));
+				Copy(mask, &mask2, sizeof(IP));
+			}
+			else if (IsIP4(&ip2) && IsIP4(&mask2))
+			{
+				// 両方とも IPv4
+				ret = true;
+				Copy(ip, &ip2, sizeof(IP));
+				Copy(mask, &mask2, sizeof(IP));
+			}
+		}
+		else
+		{
+			if (IsNum(subnetstr))
+			{
+				UINT i = ToInt(subnetstr);
+				// マスク部が数値
+				if (IsIP6(&ip2) && i <= 128)
+				{
+					ret = true;
+					Copy(ip, &ip2, sizeof(IP));
+					IntToSubnetMask6(mask, i);
+				}
+				else if (i <= 32)
+				{
+					ret = true;
+					Copy(ip, &ip2, sizeof(IP));
+					IntToSubnetMask4(mask, i);
+				}
+			}
+		}
+	}
+
+	FreeToken(t);
+
+	return ret;
+}
+bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask)
+{
+	IP ip_ip, ip_mask;
+	if (ParseIpAndMask46(src, &ip_ip, &ip_mask) == false)
+	{
+		return false;
+	}
+
+	if (IsIP4(&ip_ip) == false)
+	{
+		return false;
+	}
+
+	if (ip != NULL)
+	{
+		*ip = IPToUINT(&ip_ip);
+	}
+
+	if (mask != NULL)
+	{
+		*mask = IPToUINT(&ip_mask);
+	}
+
+	return true;
+}
+bool ParseIpAndMask6(char *src, IP *ip, IP *mask)
+{
+	if (ParseIpAndMask46(src, ip, mask) == false)
+	{
+		return false;
+	}
+
+	if (IsIP6(ip) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+
+// IPv4 アドレスの指定が正しいかどうかチェックする
+bool IsIpStr4(char *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	if (StrToIP32(str) == 0 && StrCmpi(str, "0.0.0.0") != 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// IPv6 アドレスの指定が正しいかどうかチェックする
+bool IsIpStr6(char *str)
+{
+	IP ip;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	if (StrToIP6(&ip, str) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// IP アドレスの指定が正しいかどうかチェックする
+bool IsIpStr46(char *str)
+{
+	if (IsIpStr4(str) || IsIpStr6(str))
+	{
+		return true;
+	}
+
+	return false;
+}
+
+
+// 文字列を IPv4 マスクに変換
+bool StrToMask4(IP *mask, char *str)
+{
+	// 引数チェック
+	if (mask == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	if (str[0] == '/')
+	{
+		str++;
+	}
+
+	if (IsNum(str))
+	{
+		UINT n = ToInt(str);
+
+		if (n <= 32)
+		{
+			IntToSubnetMask4(mask, n);
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+	else
+	{
+		if (StrToIP(mask, str) == false)
+		{
+			return false;
+		}
+		else
+		{
+			return IsIP4(mask);
+		}
+	}
+}
+
+// 文字列を IPv6 マスクに変換
+bool StrToMask6(IP *mask, char *str)
+{
+	// 引数チェック
+	if (mask == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	if (str[0] == '/')
+	{
+		str++;
+	}
+
+	if (IsNum(str))
+	{
+		UINT n = ToInt(str);
+
+		if (n <= 128)
+		{
+			IntToSubnetMask6(mask, n);
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+	else
+	{
+		if (StrToIP(mask, str) == false)
+		{
+			return false;
+		}
+		else
+		{
+			return IsIP6(mask);
+		}
+	}
+}
+bool StrToMask6Addr(IPV6_ADDR *mask, char *str)
+{
+	IP ip;
+
+	if (StrToMask6(&ip, str) == false)
+	{
+		return false;
+	}
+
+	if (IPToIPv6Addr(mask, &ip) == false)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// 文字列を IPv4 / IPv6 マスクに変換
+bool StrToMask46(IP *mask, char *str, bool ipv6)
+{
+	if (ipv6)
+	{
+		return StrToMask6(mask, str);
+	}
+	else
+	{
+		return StrToMask4(mask, str);
+	}
+}
+
+
+// IPv4 / IPv6 マスクを文字列に変換
+void MaskToStr(char *str, UINT size, IP *mask)
+{
+	MaskToStrEx(str, size, mask, false);
+}
+void MaskToStrEx(char *str, UINT size, IP *mask, bool always_full_address)
+{
+	// 引数チェック
+	if (str == NULL || mask == NULL)
+	{
+		return;
+	}
+
+	if (always_full_address == false && IsSubnetMask(mask))
+	{
+		ToStr(str, SubnetMaskToInt(mask));
+	}
+	else
+	{
+		IPToStr(str, size, mask);
+	}
+}
+void MaskToStr32(char *str, UINT size, UINT mask)
+{
+	MaskToStr32Ex(str, size, mask, false);
+}
+void MaskToStr32Ex(char *str, UINT size, UINT mask, bool always_full_address)
+{
+	IP ip;
+
+	UINTToIP(&ip, mask);
+
+	MaskToStrEx(str, size, &ip, always_full_address);
+}
+void Mask6AddrToStrEx(char *str, UINT size, IPV6_ADDR *mask, bool always_full_address)
+{
+	IP ip;
+
+	// 引数チェック
+	if (str == NULL || mask == NULL)
+	{
+		StrCpy(str, size, "");
+		return;
+	}
+
+	IPv6AddrToIP(&ip, mask);
+
+	MaskToStrEx(str, size, &ip, always_full_address);
+}
+void Mask6AddrToStr(char *str, UINT size, IPV6_ADDR *mask)
+{
+	Mask6AddrToStrEx(str, size, mask, false);
+}
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Network.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Network.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Network.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,703 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Network.h
+// Network.c のヘッダ
+
+#ifndef	NETWORK_H
+#define	NETWORK_H
+
+#define	TIMEOUT_GETIP				2300
+
+#define	TIMEOUT_INFINITE			(0x7fffffff)
+#define	TIMEOUT_TCP_PORT_CHECK		(10 * 1000)
+#define	TIMEOUT_SSL_CONNECT			(15 * 1000)
+
+#define	TIMEOUT_HOSTNAME			(500)
+#define	TIMEOUT_NETBIOS_HOSTNAME	(100)
+#define	EXPIRES_HOSTNAME			(10 * 60 * 1000)
+
+#define	SOCKET_BUFFER_SIZE			0x10000000
+
+#define	IPV6_DUMMY_FOR_IPV4			0xFEFFFFDF
+
+
+// IP アドレス
+struct IP
+{
+	UCHAR addr[4];					// IPv4 アドレス, ※ 223.255.255.254 = IPv6 を意味する
+	UCHAR ipv6_addr[16];			// IPv6 アドレス
+	UINT ipv6_scope_id;				// IPv6 スコープ ID
+};
+
+// IP 構造体をアドレス部分のみで比較する際のサイズ
+#define	SIZE_OF_IP_FOR_ADDR			(sizeof(UCHAR) * 20)
+
+// IP アドレス部を比較
+#define	CmpIpAddr(ip1, ip2)			(Cmp((ip1), (ip2), SIZE_OF_IP_FOR_ADDR))
+
+// IPv6 アドレス (異形式)
+struct IPV6_ADDR
+{
+	UCHAR Value[16];				// 値
+} GCC_PACKED;
+
+// IPv6アドレスの種類
+#define IPV6_ADDR_UNICAST						1	// ユニキャスト
+#define IPV6_ADDR_LOCAL_UNICAST					2	// ローカルユニキャスト
+#define IPV6_ADDR_GLOBAL_UNICAST				4	// グローバルユニキャスト
+#define IPV6_ADDR_MULTICAST						8	// マルチキャスト
+#define IPV6_ADDR_ALL_NODE_MULTICAST			16	// 全ノードマルチキャスト
+#define IPV6_ADDR_ALL_ROUTER_MULTICAST			32	// 全ルータマルチキャスト
+#define IPV6_ADDR_SOLICIATION_MULTICAST			64	// 要請ノードマルチキャスト
+#define	IPV6_ADDR_ZERO							128	// オールゼロ
+#define	IPV6_ADDR_LOOPBACK						256	// ループバック
+
+
+// DNS キャッシュリスト
+struct DNSCACHE
+{
+	char *HostName;
+	IP IpAddress;
+};
+
+// クライアントリスト
+struct IP_CLIENT
+{
+	IP IpAddress;					// IP アドレス
+	UINT NumConnections;			// 接続個数
+};
+
+// ソケットイベント
+struct SOCK_EVENT
+{
+	REF *ref;						// 参照カウンタ
+#ifdef	OS_WIN32
+	void *hEvent;					// Win32 イベントハンドルへのポインタ
+#else	// OS_WIN32
+	LIST *SockList;					// ソケットリスト
+	int pipe_read, pipe_write;		// パイプ
+#endif	// OS_WIN32
+};
+
+// ソケットの種類
+#define	SOCK_TCP				1
+#define	SOCK_UDP				2
+
+// ソケット
+struct SOCK
+{
+	REF *ref;					// 参照カウンタ
+	LOCK *lock;					// ロック
+	LOCK *ssl_lock;				// SSL 関係のロック
+	LOCK *disconnect_lock;		// 切断用ロック
+	SOCKET socket;				// ソケット番号
+	SSL *ssl;					// SSL オブジェクト
+	UINT Type;					// ソケットの種類
+	bool Connected;				// 接続中フラグ
+	bool ServerMode;			// サーバーモード
+	bool AsyncMode;				// 非同期モード
+	bool SecureMode;			// SSL 通信モード
+	bool ListenMode;			// Listen 中
+	BUF *SendBuf;				// 送信バッファ
+	IP RemoteIP;				// リモートホストの IP アドレス
+	IP LocalIP;					// ローカルホストの IP アドレス
+	char *RemoteHostname;		// リモートホスト名
+	UINT RemotePort;			// リモート側のポート番号
+	UINT LocalPort;				// ローカル側のポート番号
+	UINT64 SendSize;			// 送信したデータサイズの合計
+	UINT64 RecvSize;			// 受信したデータサイズの合計
+	UINT64 SendNum;				// 送信したデータブロック数
+	UINT64 RecvNum;				// 受信したデータブロック数
+	X *RemoteX;					// リモートホストの証明書
+	X *LocalX;					// ローカルホストの証明書
+	char *CipherName;			// 暗号化アルゴリズム名
+	char *WaitToUseCipher;		// 使用したいアルゴリズム名を設定する
+	bool IgnoreRecvErr;			// RecvFrom エラーを無視できるかどうか
+	bool IgnoreSendErr;			// SendTo エラーを無視できるかどうか
+	UINT TimeOut;				// タイムアウト値
+	SOCK_EVENT *SockEvent;		// 関連付けられているソケットイベント
+	bool CancelAccept;			// Accept のキャンセルフラグ
+	bool WriteBlocked;			// 前回の書き込みがブロックされた
+	bool Disconnecting;			// 切断しようとしている
+	bool UdpBroadcast;			// UDP ブロードキャストモード
+	void *Param;				// 任意のパラメータ
+	bool IPv6;					// IPv6
+
+#ifdef	OS_UNIX
+	pthread_t CallingThread;	// システムコールを呼び出しているスレッド
+#endif	// OS_UNIX
+
+#ifdef	OS_WIN32
+	void *hEvent;				// 非同期モードの場合のイベント
+#endif	// OS_WIN32
+};
+
+// 戻り値の定数
+#define	SOCK_LATER	(0xffffffff)	// ブロッキング中
+
+// ソケットセット
+#define	MAX_SOCKSET_NUM		60		// ソケットセットに格納できるソケット数
+struct SOCKSET
+{
+	UINT NumSocket;					// ソケット数
+	SOCK *Sock[MAX_SOCKSET_NUM];	// ソケットへのポインタの配列
+};
+
+// キャンセルオブジェクト
+struct CANCEL
+{
+	REF *ref;						// 参照カウンタ
+	bool SpecialFlag;				// 特殊フラグ (Win32 ドライバが生成したイベントを関連付ける)
+#ifdef	OS_WIN32
+	void *hEvent;					// Win32 イベントハンドルへのポインタ
+#else	// OS_WIN32
+	int pipe_read, pipe_write;		// パイプ
+#endif	// OS_WIN32
+};
+
+// ルーティングテーブルエントリ
+struct ROUTE_ENTRY
+{
+	IP DestIP;
+	IP DestMask;
+	IP GatewayIP;
+	bool LocalRouting;
+	bool PPPConnection;
+	UINT Metric;
+	UINT OldIfMetric;
+	UINT InterfaceID;
+};
+
+// ルーティングテーブル
+struct ROUTE_TABLE
+{
+	UINT NumEntry;
+	UINT HashedValue;
+	ROUTE_ENTRY **Entry;
+};
+
+// ホスト名キャッシュリスト
+typedef struct HOSTCACHE
+{
+	UINT64 Expires;							// 有効期限
+	IP IpAddress;							// IP アドレス
+	char HostName[256];						// ホスト名
+} HOSTCACHE;
+
+// NETBIOS 名前要求
+typedef struct NBTREQUEST
+{
+	USHORT TransactionId;
+	USHORT Flags;
+	USHORT NumQuestions;
+	USHORT AnswerRRs;
+	USHORT AuthorityRRs;
+	USHORT AdditionalRRs;
+	UCHAR Query[38];
+} NBTREQUEST;
+
+// NETBIOS 名前応答
+typedef struct NBTRESPONSE
+{
+	USHORT TransactionId;
+	USHORT Flags;
+	USHORT NumQuestions;
+	USHORT AnswerRRs;
+	USHORT AuthorityRRs;
+	USHORT AdditionalRRs;
+	UCHAR Response[61];
+} NBTRESPONSE;
+
+// ソケットリスト
+typedef struct SOCKLIST
+{
+	LIST *SockList;
+} SOCKLIST;
+
+
+// Solaris 用タイムアウトスレッドのパラメータ
+typedef struct SOCKET_TIMEOUT_PARAM{
+	SOCK *sock;
+	CANCEL *cancel;
+	THREAD *thread;
+	bool unblocked;
+} SOCKET_TIMEOUT_PARAM;
+
+// GetIP 用スレッドのパラメータ
+struct GETIP_THREAD_PARAM
+{
+	REF *Ref;
+	char HostName[MAX_PATH];
+	bool IPv6;
+	UINT Timeout;
+	IP Ip;
+	bool Ok;
+};
+
+// IP アドレスリリース用スレッドのパラメータ
+struct WIN32_RELEASEADDRESS_THREAD_PARAM
+{
+	REF *Ref;
+	char Guid[MAX_SIZE];
+	UINT Timeout;
+	bool Ok;
+	bool Renew;
+};
+
+// TCP テーブルエントリ
+typedef struct TCPTABLE
+{
+	UINT Status;
+	IP LocalIP;
+	UINT LocalPort;
+	IP RemoteIP;
+	UINT RemotePort;
+	UINT ProcessId;
+} TCPTABLE;
+
+// TCP の状態
+#define	TCP_STATE_CLOSED				1
+#define	TCP_STATE_LISTEN				2
+#define	TCP_STATE_SYN_SENT				3
+#define	TCP_STATE_SYN_RCVD				4
+#define	TCP_STATE_ESTAB					5
+#define	TCP_STATE_FIN_WAIT1				6
+#define	TCP_STATE_FIN_WAIT2				7
+#define	TCP_STATE_CLOSE_WAIT			8
+#define	TCP_STATE_CLOSING				9
+#define	TCP_STATE_LAST_ACK				10
+#define	TCP_STATE_TIME_WAIT				11
+#define	TCP_STATE_DELETE_TCB			12
+
+// ルーティングテーブル変化通知
+struct ROUTE_CHANGE
+{
+	ROUTE_CHANGE_DATA *Data;
+};
+
+
+#ifdef	OS_WIN32
+
+// Win32 用関数プロトタイプ
+void Win32InitSocketLibrary();
+void Win32FreeSocketLibrary();
+void Win32Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2);
+void Win32InitAsyncSocket(SOCK *sock);
+void Win32JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event);
+void Win32FreeAsyncSocket(SOCK *sock);
+void Win32IpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row);
+void Win32RouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry);
+int Win32CompareRouteEntryByMetric(void *p1, void *p2);
+ROUTE_TABLE *Win32GetRouteTable();
+bool Win32AddRouteEntry(ROUTE_ENTRY *e, bool *already_exists);
+void Win32DeleteRouteEntry(ROUTE_ENTRY *e);
+void Win32UINTToIP(IP *ip, UINT i);
+UINT Win32IPToUINT(IP *ip);
+UINT Win32GetVLanInterfaceID(char *instance_name);
+char **Win32EnumVLan(char *tag_name);
+void Win32Cancel(CANCEL *c);
+void Win32CleanupCancel(CANCEL *c);
+CANCEL *Win32NewCancel();
+SOCK_EVENT *Win32NewSockEvent();
+void Win32SetSockEvent(SOCK_EVENT *event);
+void Win32CleanupSockEvent(SOCK_EVENT *event);
+bool Win32WaitSockEvent(SOCK_EVENT *event, UINT timeout);
+bool Win32GetDefaultDns(IP *ip, char *domain, UINT size);
+void Win32RenewDhcp();
+void Win32RenewDhcp9x(UINT if_id);
+void Win32ReleaseDhcp9x(UINT if_id, bool wait);
+int CompareIpAdapterIndexMap(void *p1, void *p2);
+LIST *Win32GetTcpTableList();
+LIST *Win32GetTcpTableListByGetExtendedTcpTable();
+LIST *Win32GetTcpTableListByAllocateAndGetTcpExTableFromStack();
+LIST *Win32GetTcpTableListByGetTcpTable();
+ROUTE_CHANGE *Win32NewRouteChange();
+void Win32FreeRouteChange(ROUTE_CHANGE *r);
+bool Win32IsRouteChanged(ROUTE_CHANGE *r);
+bool Win32GetAdapterFromGuid(void *a, char *guid);
+
+bool Win32ReleaseAddress(void *a);
+bool Win32ReleaseAddressByGuid(char *guid);
+bool Win32ReleaseAddressByGuidEx(char *guid, UINT timeout);
+void Win32ReleaseAddressByGuidExThread(THREAD *t, void *param);
+void ReleaseWin32ReleaseAddressByGuidThreadParam(WIN32_RELEASEADDRESS_THREAD_PARAM *p);
+bool Win32ReleaseOrRenewAddressByGuidEx(char *guid, UINT timeout, bool renew);
+bool Win32RenewAddress(void *a);
+bool Win32RenewAddressByGuid(char *guid);
+bool Win32RenewAddressByGuidEx(char *guid, UINT timeout);
+
+
+#else	// OS_WIN32
+
+// UNIX 用関数プロトタイプ
+void UnixInitSocketLibrary();
+void UnixFreeSocketLibrary();
+void UnixSelect(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2);
+void UnixInitAsyncSocket(SOCK *sock);
+void UnixJoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event);
+void UnixFreeAsyncSocket(SOCK *sock);
+void UnixIpForwardRowToRouteEntry(ROUTE_ENTRY *entry, void *ip_forward_row);
+void UnixRouteEntryToIpForwardRow(void *ip_forward_row, ROUTE_ENTRY *entry);
+int UnixCompareRouteEntryByMetric(void *p1, void *p2);
+ROUTE_TABLE *UnixGetRouteTable();
+bool UnixAddRouteEntry(ROUTE_ENTRY *e, bool *already_exists);
+void UnixDeleteRouteEntry(ROUTE_ENTRY *e);
+UINT UnixGetVLanInterfaceID(char *instance_name);
+char **UnixEnumVLan(char *tag_name);
+void UnixCancel(CANCEL *c);
+void UnixCleanupCancel(CANCEL *c);
+CANCEL *UnixNewCancel();
+SOCK_EVENT *UnixNewSockEvent();
+void UnixSetSockEvent(SOCK_EVENT *event);
+void UnixCleanupSockEvent(SOCK_EVENT *event);
+bool UnixWaitSockEvent(SOCK_EVENT *event, UINT timeout);
+bool UnixGetDefaultDns(IP *ip);
+void UnixRenewDhcp();
+void UnixNewPipe(int *pipe_read, int *pipe_write);
+void UnixWritePipe(int pipe_write);
+void UnixDeletePipe(int p1, int p2);
+void UnixSelectInner(UINT num_read, UINT *reads, UINT num_write, UINT *writes, UINT timeout);
+void UnixSetSocketNonBlockingMode(int fd, bool nonblock);
+
+#endif	// OS_WIN32
+
+// 関数プロトタイプ
+void InitNetwork();
+void FreeNetwork();
+void InitDnsCache();
+void FreeDnsCache();
+void LockDnsCache();
+void UnlockDnsCache();
+int CompareDnsCache(void *p1, void *p2);
+void GenDnsCacheKeyName(char *dst, UINT size, char *src, bool ipv6);
+void NewDnsCacheEx(char *hostname, IP *ip, bool ipv6);
+DNSCACHE *FindDnsCacheEx(char *hostname, bool ipv6);
+bool QueryDnsCacheEx(IP *ip, char *hostname, bool ipv6);
+void NewDnsCache(char *hostname, IP *ip);
+DNSCACHE *FindDnsCache(char *hostname);
+bool QueryDnsCache(IP *ip, char *hostname);
+void InAddrToIP(IP *ip, struct in_addr *addr);
+void InAddrToIP6(IP *ip, struct in6_addr *addr);
+void IPToInAddr(struct in_addr *addr, IP *ip);
+void IPToInAddr6(struct in6_addr *addr, IP *ip);
+bool StrToIP(IP *ip, char *str);
+UINT StrToIP32(char *str);
+bool UniStrToIP(IP *ip, wchar_t *str);
+UINT UniStrToIP32(wchar_t *str);
+void IPToStr(char *str, UINT size, IP *ip);
+void IPToStr4(char *str, UINT size, IP *ip);
+void IPToStr32(char *str, UINT size, UINT ip);
+void IPToStr128(char *str, UINT size, UCHAR *ip_bytes);
+void IPToStr4or6(char *str, UINT size, UINT ip_4_uint, UCHAR *ip_6_bytes);
+void IPToUniStr(wchar_t *str, UINT size, IP *ip);
+void IPToUniStr32(wchar_t *str, UINT size, UINT ip);
+bool GetIPEx(IP *ip, char *hostname, bool ipv6);
+bool GetIP46(IP *ip4, IP *ip6, char *hostname);
+bool GetIP46Ex(IP *ip4, IP *ip6, char *hostname, UINT timeout, bool *cancel);
+bool GetIP46Any4(IP *ip, char *hostname);
+bool GetIP46Any6(IP *ip, char *hostname);
+bool GetIP(IP *ip, char *hostname);
+bool GetIP4(IP *ip, char *hostname);
+bool GetIP6(IP *ip, char *hostname);
+bool GetIP4Ex(IP *ip, char *hostname, UINT timeout, bool *cancel);
+bool GetIP6Ex(IP *ip, char *hostname, UINT timeout, bool *cancel);
+bool GetIP4Ex6Ex(IP *ip, char *hostname, UINT timeout, bool ipv6, bool *cancel);
+void GetIP4Ex6ExThread(THREAD *t, void *param);
+void ReleaseGetIPThreadParam(GETIP_THREAD_PARAM *p);
+void CleanupGetIPThreadParam(GETIP_THREAD_PARAM *p);
+bool GetIP4Inner(IP *ip, char *hostname);
+bool GetIP6Inner(IP *ip, char *hostname);
+bool GetHostNameInner(char *hostname, UINT size, IP *ip);
+bool GetHostNameInner6(char *hostname, UINT size, IP *ip);
+bool GetHostName(char *hostname, UINT size, IP *ip);
+void GetHostNameThread(THREAD *t, void *p);
+void GetMachineName(char *name, UINT size);
+void GetMachineNameEx(char *name, UINT size, bool no_load_hosts);
+bool GetMachineNameFromHosts(char *name, UINT size);
+void GetMachineIp(IP *ip);
+void GetMachineHostName(char *name, UINT size);
+void UINTToIP(IP *ip, UINT value);
+UINT IPToUINT(IP *ip);
+SOCK *NewSock();
+void ReleaseSock(SOCK *s);
+void CleanupSock(SOCK *s);
+SOCK *Connect(char *hostname, UINT port);
+SOCK *ConnectEx(char *hostname, UINT port, UINT timeout);
+SOCK *ConnectEx2(char *hostname, UINT port, UINT timeout, bool *cancel_flag);
+void SetSocketSendRecvBufferSize(int s, UINT size);
+void QuerySocketInformation(SOCK *sock);
+void Disconnect(SOCK *sock);
+SOCK *Listen(UINT port);
+SOCK *ListenEx(UINT port, bool local_only);
+SOCK *Listen6(UINT port);
+SOCK *ListenEx6(UINT port, bool local_only);
+SOCK *Accept(SOCK *sock);
+SOCK *Accept6(SOCK *sock);
+UINT Send(SOCK *sock, void *data, UINT size, bool secure);
+UINT Recv(SOCK *sock, void *data, UINT size, bool secure);
+UINT SecureSend(SOCK *sock, void *data, UINT size);
+UINT SecureRecv(SOCK *sock, void *data, UINT size);
+bool StartSSL(SOCK *sock, X *x, K *priv);
+bool StartSSLEx(SOCK *sock, X *x, K *priv, bool client_tls);
+bool SendAll(SOCK *sock, void *data, UINT size, bool secure);
+void SendAdd(SOCK *sock, void *data, UINT size);
+bool SendNow(SOCK *sock, int secure);
+bool RecvAll(SOCK *sock, void *data, UINT size, bool secure);
+void InitSockSet(SOCKSET *set);
+void AddSockSet(SOCKSET *set, SOCK *sock);
+CANCEL *NewCancel();
+CANCEL *NewCancelSpecial(void *hEvent);
+void ReleaseCancel(CANCEL *c);
+void CleanupCancel(CANCEL *c);
+void Cancel(CANCEL *c);
+void Select(SOCKSET *set, UINT timeout, CANCEL *c1, CANCEL *c2);
+void SetWantToUseCipher(SOCK *sock, char *name);
+SOCK *NewUDP(UINT port);
+SOCK *NewUDPEx(UINT port, bool ipv6);
+SOCK *NewUDP4(UINT port);
+SOCK *NewUDP6(UINT port);
+UINT SendTo(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size);
+UINT SendTo6(SOCK *sock, IP *dest_addr, UINT dest_port, void *data, UINT size);
+UINT RecvFrom(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size);
+UINT RecvFrom6(SOCK *sock, IP *src_addr, UINT *src_port, void *data, UINT size);
+void SetTimeout(SOCK *sock, UINT timeout);
+UINT GetTimeout(SOCK *sock);
+void LockOpenSSL();
+void UnlockOpenSSL();
+bool CheckTCPPort(char *hostname, UINT port);
+bool CheckTCPPortEx(char *hostname, UINT port, UINT timeout);
+void CheckTCPPortThread(THREAD *thread, void *param);
+ROUTE_TABLE *GetRouteTable();
+void FreeRouteTable(ROUTE_TABLE *t);
+bool AddRouteEntryEx(ROUTE_ENTRY *e, bool *already_exists);
+bool AddRouteEntry(ROUTE_ENTRY *e);
+void DeleteRouteEntry(ROUTE_ENTRY *e);
+char **EnumVLan(char *tag_name);
+void FreeEnumVLan(char **s);
+UINT GetVLanInterfaceID(char *tag_name);
+ROUTE_ENTRY *GetBestRouteEntry(IP *ip);
+ROUTE_ENTRY *GetBestRouteEntryEx(IP *ip, UINT exclude_if_id);
+ROUTE_ENTRY *GetBestRouteEntryFromRouteTable(ROUTE_TABLE *table, IP *ip);
+ROUTE_ENTRY *GetBestRouteEntryFromRouteTableEx(ROUTE_TABLE *table, IP *ip, UINT exclude_if_id);
+void FreeRouteEntry(ROUTE_ENTRY *e);
+void JoinSockToSockEvent(SOCK *sock, SOCK_EVENT *event);
+SOCK_EVENT *NewSockEvent();
+void SetSockEvent(SOCK_EVENT *event);
+void CleanupSockEvent(SOCK_EVENT *event);
+bool WaitSockEvent(SOCK_EVENT *event, UINT timeout);
+void ReleaseSockEvent(SOCK_EVENT *event);
+void SetIP(IP *ip, UCHAR a1, UCHAR a2, UCHAR a3, UCHAR a4);
+bool GetDefaultDns(IP *ip);
+bool GetDomainName(char *name, UINT size);
+bool UnixGetDomainName(char *name, UINT size);
+void RenewDhcp();
+void AcceptInit(SOCK *s);
+bool CheckCipherListName(char *name);
+TOKEN_LIST *GetCipherList();
+COUNTER *GetNumTcpConnectionsCounter();
+void InitWaitThread();
+void FreeWaitThread();
+void AddWaitThread(THREAD *t);
+void DelWaitThread(THREAD *t);
+void InitHostCache();
+void FreeHostCache();
+int CompareHostCache(void *p1, void *p2);
+void AddHostCache(IP *ip, char *hostname);
+bool GetHostCache(char *hostname, UINT size, IP *ip);
+bool IsSubnetMask(IP *ip);
+bool IsSubnetMask4(IP *ip);
+bool IsSubnetMask32(UINT ip);
+bool IsNetworkAddress(IP *ip, IP *mask);
+bool IsNetworkAddress4(IP *ip, IP *mask);
+bool IsNetworkAddress32(UINT ip, UINT mask);
+bool IsHostIPAddress4(IP *ip);
+bool IsHostIPAddress32(UINT ip);
+bool IsZeroIp(IP *ip);
+bool IsZeroIP(IP *ip);
+bool IsZeroIP6Addr(IPV6_ADDR *addr);
+UINT IntToSubnetMask32(UINT i);
+void IntToSubnetMask4(IP *ip, UINT i);
+bool GetNetBiosName(char *name, UINT size, IP *ip);
+bool NormalizeMacAddress(char *dst, UINT size, char *src);
+SOCKLIST *NewSockList();
+void AddSockList(SOCKLIST *sl, SOCK *s);
+void DelSockList(SOCKLIST *sl, SOCK *s);
+void StopSockList(SOCKLIST *sl);
+void FreeSockList(SOCKLIST *sl);
+bool IsIPv6Supported();
+void SetSockPriorityHigh(SOCK *s);
+void InitIpClientList();
+void FreeIpClientList();
+int CompareIpClientList(void *p1, void *p2);
+void AddIpClient(IP *ip);
+void DelIpClient(IP *ip);
+IP_CLIENT *SearchIpClient(IP *ip);
+UINT GetNumIpClient(IP *ip);
+void SetLinuxArpFilter();
+LIST *GetTcpTableList();
+void FreeTcpTableList(LIST *o);
+int CompareTcpTable(void *p1, void *p2);
+void PrintTcpTableList(LIST *o);
+TCPTABLE *GetTcpTableFromEndPoint(LIST *o, IP *local_ip, UINT local_port, IP *remote_ip, UINT remote_port);
+UINT GetTcpProcessIdFromSocket(SOCK *s);
+UINT GetTcpProcessIdFromSocketReverse(SOCK *s);
+bool CanGetTcpProcessId();
+int connect_timeout(SOCKET s, struct sockaddr *addr, int size, int timeout, bool *cancel_flag);
+void EnableNetworkNameCache();
+void DisableNetworkNameCache();
+bool IsNetworkNameCacheEnabled();
+ROUTE_CHANGE *NewRouteChange();
+void FreeRouteChange(ROUTE_CHANGE *r);
+bool IsRouteChanged(ROUTE_CHANGE *r);
+void RouteToStr(char *str, UINT str_size, ROUTE_ENTRY *e);
+void DebugPrintRoute(ROUTE_ENTRY *e);
+void DebugPrintRouteTable(ROUTE_TABLE *r);
+
+void SocketTimeoutThread(THREAD *t, void *param);
+SOCKET_TIMEOUT_PARAM *NewSocketTimeout(SOCK *sock);
+void FreeSocketTimeout(SOCKET_TIMEOUT_PARAM *ttp);
+
+bool CheckSubnetLength6(UINT i);
+bool IsIP6(IP *ip);
+bool IsIP4(IP *ip);
+void IPv6AddrToIP(IP *ip, IPV6_ADDR *addr);
+bool IPToIPv6Addr(IPV6_ADDR *addr, IP *ip);
+void SetIP6(IP *ip, UCHAR *value);
+void GetLocalHostIP6(IP *ip);
+void ZeroIP6(IP *ip);
+void ZeroIP4(IP *ip);
+bool CheckIPItemStr6(char *str);
+void IPItemStrToChars6(UCHAR *chars, char *str);
+bool StrToIP6(IP *ip, char *str);
+bool StrToIP6Addr(IPV6_ADDR *ip, char *str);
+void IPToStr6(char *str, UINT size, IP *ip);
+void IP6AddrToStr(char *str, UINT size, IPV6_ADDR *addr);
+void IPToStr6Array(char *str, UINT size, UCHAR *bytes);
+void IPToStr6Inner(char *str, IP *ip);
+void IntToSubnetMask6(IP *ip, UINT i);
+void IPNot6(IP *dst, IP *a);
+void IPOr6(IP *dst, IP *a, IP *b);
+void IPAnd6(IP *dst, IP *a, IP *b);
+void GetAllRouterMulticastAddress6(IP *ip);
+void GetAllNodeMulticaseAddress6(IP *ip);
+void GetLoopbackAddress6(IP *ip);
+void GetAllFilledAddress6(IP *ip);
+UINT GetIPAddrType6(IP *ip);
+UINT GetIPv6AddrType(IPV6_ADDR *addr);
+void GenerateMulticastMacAddress6(UCHAR *mac, IP *ip);
+void GetSoliciationMulticastAddr6(IP *dst, IP *src);
+bool CheckUnicastAddress(IP *ip);
+bool IsNetworkPrefixAddress6(IP *ip, IP *subnet);
+bool IsNetworkAddress6(IP *ip, IP *subnet);
+void GetHostAddress6(IP *dst, IP *ip, IP *subnet);
+void GetPrefixAddress6(IP *dst, IP *ip, IP *subnet);
+bool IsNetworkPrefixAddress6(IP *ip, IP *subnet);
+bool IsInSameNetwork6(IP *a1, IP *a2, IP *subnet);
+void GenerateEui64Address6(UCHAR *dst, UCHAR *mac);
+void GenerateEui64LocalAddress(IP *a, UCHAR *mac);
+void GenerateEui64GlobalAddress(IP *ip, IP *prefix, IP *subnet, UCHAR *mac);
+bool IsSubnetMask6(IP *a);
+UINT SubnetMaskToInt(IP *a);
+UINT SubnetMaskToInt6(IP *a);
+UINT SubnetMaskToInt4(IP *a);
+bool IsStrIPv6Address(char *str);
+
+bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask);
+bool ParseIpAndSubnetMask6(char *src, IP *ip, IP *mask);
+bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask);
+bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask);
+bool ParseIpAndMask6(char *src, IP *ip, IP *mask);
+bool ParseIpAndMask46(char *src, IP *ip, IP *mask);
+bool IsIpStr4(char *str);
+bool IsIpStr6(char *str);
+bool IsIpMask6(char *str);
+bool IsIpStr46(char *str);
+bool StrToMask4(IP *mask, char *str);
+bool StrToMask6(IP *mask, char *str);
+bool StrToMask6Addr(IPV6_ADDR *mask, char *str);
+bool StrToMask46(IP *mask, char *str, bool ipv6);
+void MaskToStr(char *str, UINT size, IP *mask);
+void Mask6AddrToStrEx(char *str, UINT size, IPV6_ADDR *mask, bool always_full_address);
+void Mask6AddrToStr(char *str, UINT size, IPV6_ADDR *mask);
+void MaskToStr32(char *str, UINT size, UINT mask);
+void MaskToStr32Ex(char *str, UINT size, UINT mask, bool always_full_address);
+void MaskToStrEx(char *str, UINT size, IP *mask, bool always_full_address);
+
+
+#endif	// NETWORK_H
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/OS.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/OS.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/OS.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,510 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// OS.c
+// オペレーティングシステム依存コード
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+#undef	Lock
+#undef	Unlock
+
+// ディスパッチテーブル
+static OS_DISPATCH_TABLE *os = NULL;
+
+// OS 種類を文字列に変換
+char *OsTypeToStr(UINT type)
+{
+	switch (type)
+	{
+	case 0:
+		return "Unsupported OS by SoftEther Corporation\0\n";
+	case OSTYPE_WINDOWS_95:
+		return "Windows 95\0\n";
+	case OSTYPE_WINDOWS_98:
+		return "Windows 98\0\n";
+	case OSTYPE_WINDOWS_ME:
+		return "Windows Millennium Edition\0\n";
+	case OSTYPE_WINDOWS_UNKNOWN:
+		return "Windows 9x Unknown Version\0\n";
+	case OSTYPE_WINDOWS_NT_4_WORKSTATION:
+		return "Windows NT 4.0 Workstation\0\n";
+	case OSTYPE_WINDOWS_NT_4_SERVER:
+		return "Windows NT 4.0 Server\0\n";
+	case OSTYPE_WINDOWS_NT_4_SERVER_ENTERPRISE:
+		return "Windows NT 4.0 Server, Enterprise Edition\0\n";
+	case OSTYPE_WINDOWS_NT_4_BACKOFFICE:
+		return "BackOffice Server 4.5\0\n";
+	case OSTYPE_WINDOWS_NT_4_SMS:
+		return "Small Business Server 4.5\0\n";
+	case OSTYPE_WINDOWS_2000_PROFESSIONAL:
+		return "Windows 2000 Professional\0\n";
+	case OSTYPE_WINDOWS_2000_SERVER:
+		return "Windows 2000 Server\0\n";
+	case OSTYPE_WINDOWS_2000_ADVANCED_SERVER:
+		return "Windows 2000 Advanced Server\0\n";
+	case OSTYPE_WINDOWS_2000_DATACENTER_SERVER:
+		return "Windows 2000 Datacenter Server\0\n";
+	case OSTYPE_WINDOWS_2000_BACKOFFICE:
+		return "BackOffice Server 2000\0\n";
+	case OSTYPE_WINDOWS_2000_SBS:
+		return "Small Business Server 2000\0\n";
+	case OSTYPE_WINDOWS_XP_HOME:
+		return "Windows XP Home Edition\0\n";
+	case OSTYPE_WINDOWS_XP_PROFESSIONAL:
+		return "Windows XP Professional\0\n";
+	case OSTYPE_WINDOWS_2003_WEB:
+		return "Windows Server 2003 Web Edition\0\n";
+	case OSTYPE_WINDOWS_2003_STANDARD:
+		return "Windows Server 2003 Standard Edition\0\n";
+	case OSTYPE_WINDOWS_2003_ENTERPRISE:
+		return "Windows Server 2003 Enterprise Edition\0\n";
+	case OSTYPE_WINDOWS_2003_DATACENTER:
+		return "Windows Server 2003 Datacenter Edition\0\n";
+	case OSTYPE_WINDOWS_2003_BACKOFFICE:
+		return "BackOffice Server 2003\0\n";
+	case OSTYPE_WINDOWS_2003_SBS:
+		return "Small Business Server 2003\0\n";
+	case OSTYPE_WINDOWS_LONGHORN_PROFESSIONAL:
+		return "Windows Vista\0\n";
+	case OSTYPE_WINDOWS_LONGHORN_SERVER:
+		return "Windows Server 2008\0\n";
+	case OSTYPE_WINDOWS_7:
+		return "Windows 7\0\n";
+	case OSTYPE_WINDOWS_SERVER_2008_R2:
+		return "Windows Server 2008 R2\0\n";
+	case OSTYPE_WINDOWS_8:
+		return "Windows 8 or greater\0\n";
+	case OSTYPE_WINDOWS_SERVER_8:
+		return "Windows Server 8 or greater\0\n";
+	case OSTYPE_UNIX_UNKNOWN:
+		return "UNIX System\0\n";
+	case OSTYPE_LINUX:
+		return "Linux\0\n";
+	case OSTYPE_SOLARIS:
+		return "Sun Solaris\0\n";
+	case OSTYPE_CYGWIN:
+		return "Gnu Sygwin\0\n";
+	case OSTYPE_BSD:
+		return "BSD System\0\n";
+	case OSTYPE_MACOS_X:
+		return "Mac OS X\0\n";
+	}
+
+	return "Unknown OS";
+}
+
+// 初期化
+void OSInit()
+{
+	// ディスパッチテーブルの取得
+#ifdef	OS_WIN32
+	os = Win32GetDispatchTable();
+#else	// OS_WIN32
+	os = UnixGetDispatchTable();
+#endif	// OS_WIN32
+
+	// OS 固有の初期化関数の呼び出し
+	os->Init();
+}
+
+// 解放
+void OSFree()
+{
+	os->Free();
+}
+
+// メモリ情報取得
+void OSGetMemInfo(MEMINFO *info)
+{
+	// 引数チェック
+	if (info == NULL)
+	{
+		return;
+	}
+
+	os->GetMemInfo(info);
+}
+
+// イールド
+void OSYield()
+{
+	os->Yield();
+}
+
+// シングルインスタンス開始
+void *OSNewSingleInstance(char *instance_name)
+{
+	return os->NewSingleInstance(instance_name);
+}
+
+void OSFreeSingleInstance(void *data)
+{
+	os->FreeSingleInstance(data);
+}
+
+// 優先順位を上げる
+void OSSetHighPriority()
+{
+	os->SetHighPriority();
+}
+
+// 優先順位を戻す
+void OSRestorePriority()
+{
+	os->RestorePriority();
+}
+
+// プロダクト ID の取得
+char* OSGetProductId()
+{
+	return os->GetProductId();
+}
+
+// OS がサポートされているかどうかチェックする
+bool OSIsSupportedOs()
+{
+	return os->IsSupportedOs();
+}
+
+// OS 情報の取得
+void OSGetOsInfo(OS_INFO *info)
+{
+	os->GetOsInfo(info);
+}
+
+// アラートの表示
+void OSAlert(char *msg, char *caption)
+{
+	os->Alert(msg, caption);
+}
+void OSAlertW(wchar_t *msg, wchar_t *caption)
+{
+	os->AlertW(msg, caption);
+}
+
+// プロセス起動
+bool OSRun(char *filename, char *arg, bool hide, bool wait)
+{
+	return os->Run(filename, arg, hide, wait);
+}
+bool OSRunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait)
+{
+	return os->RunW(filename, arg, hide, wait);
+}
+
+// スレッド ID の取得
+UINT OSThreadId()
+{
+	return os->ThreadId();
+}
+
+// リネーム
+bool OSFileRename(char *old_name, char *new_name)
+{
+	return os->FileRename(old_name, new_name);
+}
+bool OSFileRenameW(wchar_t *old_name, wchar_t *new_name)
+{
+	return os->FileRenameW(old_name, new_name);
+}
+
+// ファイルサイズを取得する
+UINT64 OSFileSize(void *pData)
+{
+	return os->FileSize(pData);
+}
+
+// ファイルをシークする
+bool OSFileSeek(void *pData, UINT mode, int offset)
+{
+	return os->FileSeek(pData, mode, offset);
+}
+
+// ファイルを削除する
+bool OSFileDelete(char *name)
+{
+	return os->FileDelete(name);
+}
+bool OSFileDeleteW(wchar_t *name)
+{
+	return os->FileDeleteW(name);
+}
+
+// ディレクトリを作成する
+bool OSMakeDir(char *name)
+{
+	return os->MakeDir(name);
+}
+bool OSMakeDirW(wchar_t *name)
+{
+	return os->MakeDirW(name);
+}
+
+// ディレクトリを削除する
+bool OSDeleteDir(char *name)
+{
+	return os->DeleteDir(name);
+}
+bool OSDeleteDirW(wchar_t *name)
+{
+	return os->DeleteDirW(name);
+}
+
+// ファイルを開く
+void *OSFileOpen(char *name, bool write_mode, bool read_lock)
+{
+	return os->FileOpen(name, write_mode, read_lock);
+}
+void *OSFileOpenW(wchar_t *name, bool write_mode, bool read_lock)
+{
+	return os->FileOpenW(name, write_mode, read_lock);
+}
+
+// ファイルを作成する
+void *OSFileCreate(char *name)
+{
+	return os->FileCreate(name);
+}
+void *OSFileCreateW(wchar_t *name)
+{
+	return os->FileCreateW(name);
+}
+
+// ファイルに書き込む
+bool OSFileWrite(void *pData, void *buf, UINT size)
+{
+	return os->FileWrite(pData, buf, size);
+}
+
+// ファイルから読み込む
+bool OSFileRead(void *pData, void *buf, UINT size)
+{
+	return os->FileRead(pData, buf, size);
+}
+
+// ファイルを閉じる
+void OSFileClose(void *pData, bool no_flush)
+{
+	os->FileClose(pData, no_flush);
+}
+
+// ファイルのフラッシュ
+void OSFileFlush(void *pData)
+{
+	os->FileFlush(pData);
+}
+
+// コールスタックの取得
+CALLSTACK_DATA *OSGetCallStack()
+{
+	return os->GetCallStack();
+}
+
+// シンボル情報の取得
+bool OSGetCallStackSymbolInfo(CALLSTACK_DATA *s)
+{
+	return os->GetCallStackSymbolInfo(s);
+}
+
+// スレッドの終了を待機
+bool OSWaitThread(THREAD *t)
+{
+	return os->WaitThread(t);
+}
+
+// スレッドの解放
+void OSFreeThread(THREAD *t)
+{
+	os->FreeThread(t);
+}
+
+// スレッドの初期化
+bool OSInitThread(THREAD *t)
+{
+	return os->InitThread(t);
+}
+
+// メモリ確保
+void *OSMemoryAlloc(UINT size)
+{
+	return os->MemoryAlloc(size);
+}
+
+// メモリ再確保
+void *OSMemoryReAlloc(void *addr, UINT size)
+{
+	return os->MemoryReAlloc(addr, size);
+}
+
+// メモリ解放
+void OSMemoryFree(void *addr)
+{
+	os->MemoryFree(addr);
+}
+
+// システムタイマの取得
+UINT OSGetTick()
+{
+	return os->GetTick();
+}
+
+// システム時刻の取得
+void OSGetSystemTime(SYSTEMTIME *system_time)
+{
+	os->GetSystemTime(system_time);
+}
+
+// 32bit インクリメント
+void OSInc32(UINT *value)
+{
+	os->Inc32(value);
+}
+
+// 32bit デクリメント
+void OSDec32(UINT *value)
+{
+	os->Dec32(value);
+}
+
+// スレッドの休止
+void OSSleep(UINT time)
+{
+	os->Sleep(time);
+}
+
+// ロック作成
+LOCK *OSNewLock()
+{
+	return os->NewLock();
+}
+
+// ロック
+bool OSLock(LOCK *lock)
+{
+	return os->Lock(lock);
+}
+
+// ロック解除
+void OSUnlock(LOCK *lock)
+{
+	os->Unlock(lock);
+}
+
+// ロック削除
+void OSDeleteLock(LOCK *lock)
+{
+	os->DeleteLock(lock);
+}
+
+// イベント初期化
+void OSInitEvent(EVENT *event)
+{
+	os->InitEvent(event);
+}
+
+// イベントのセット
+void OSSetEvent(EVENT *event)
+{
+	os->SetEvent(event);
+}
+
+// イベントのリセット
+void OSResetEvent(EVENT *event)
+{
+	os->ResetEvent(event);
+}
+
+// イベントの待機
+bool OSWaitEvent(EVENT *event, UINT timeout)
+{
+	return os->WaitEvent(event, timeout);
+}
+
+// イベントの解放
+void OSFreeEvent(EVENT *event)
+{
+	os->FreeEvent(event);
+}
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/OS.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/OS.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/OS.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,213 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// OS.h
+// OS.c のヘッダ
+
+#ifndef	OS_H
+#define	OS_H
+
+// 関数プロトタイプ
+char *OsTypeToStr(UINT type);
+
+void OSInit();
+void OSFree();
+void *OSMemoryAlloc(UINT size);
+void *OSMemoryReAlloc(void *addr, UINT size);
+void OSMemoryFree(void *addr);
+UINT OSGetTick();
+void OSGetSystemTime(SYSTEMTIME *system_time);
+void OSInc32(UINT *value);
+void OSDec32(UINT *value);
+void OSSleep(UINT time);
+LOCK *OSNewLock();
+bool OSLock(LOCK *lock);
+void OSUnlock(LOCK *lock);
+void OSDeleteLock(LOCK *lock);
+void OSInitEvent(EVENT *event);
+void OSSetEvent(EVENT *event);
+void OSResetEvent(EVENT *event);
+bool OSWaitEvent(EVENT *event, UINT timeout);
+void OSFreeEvent(EVENT *event);
+bool OSWaitThread(THREAD *t);
+void OSFreeThread(THREAD *t);
+bool OSInitThread(THREAD *t);
+void *OSFileOpen(char *name, bool write_mode, bool read_lock);
+void *OSFileOpenW(wchar_t *name, bool write_mode, bool read_lock);
+void *OSFileCreate(char *name);
+void *OSFileCreateW(wchar_t *name);
+bool OSFileWrite(void *pData, void *buf, UINT size);
+bool OSFileRead(void *pData, void *buf, UINT size);
+void OSFileClose(void *pData, bool no_flush);
+void OSFileFlush(void *pData);
+UINT64 OSFileSize(void *pData);
+bool OSFileSeek(void *pData, UINT mode, int offset);
+bool OSFileDelete(char *name);
+bool OSFileDeleteW(wchar_t *name);
+bool OSMakeDir(char *name);
+bool OSMakeDirW(wchar_t *name);
+bool OSDeleteDir(char *name);
+bool OSDeleteDirW(wchar_t *name);
+CALLSTACK_DATA *OSGetCallStack();
+bool OSGetCallStackSymbolInfo(CALLSTACK_DATA *s);
+bool OSFileRename(char *old_name, char *new_name);
+bool OSFileRenameW(wchar_t *old_name, wchar_t *new_name);
+UINT OSThreadId();
+bool OSRun(char *filename, char *arg, bool hide, bool wait);
+bool OSRunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait);
+bool OSIsSupportedOs();
+void OSGetOsInfo(OS_INFO *info);
+void OSAlert(char *msg, char *caption);
+void OSAlertW(wchar_t *msg, wchar_t *caption);
+char* OSGetProductId();
+void OSSetHighPriority();
+void OSRestorePriority();
+void *OSNewSingleInstance(char *instance_name);
+void OSFreeSingleInstance(void *data);
+void OSGetMemInfo(MEMINFO *info);
+void OSYield();
+
+// ディスパッチテーブル
+typedef struct OS_DISPATCH_TABLE
+{
+	void (*Init)();
+	void (*Free)();
+	void *(*MemoryAlloc)(UINT size);
+	void *(*MemoryReAlloc)(void *addr, UINT size);
+	void (*MemoryFree)(void *addr);
+	UINT (*GetTick)();
+	void (*GetSystemTime)(SYSTEMTIME *system_time);
+	void (*Inc32)(UINT *value);
+	void (*Dec32)(UINT *value);
+	void (*Sleep)(UINT time);
+	LOCK *(*NewLock)();
+	bool (*Lock)(LOCK *lock);
+	void (*Unlock)(LOCK *lock);
+	void (*DeleteLock)(LOCK *lock);
+	void (*InitEvent)(EVENT *event);
+	void (*SetEvent)(EVENT *event);
+	void (*ResetEvent)(EVENT *event);
+	bool (*WaitEvent)(EVENT *event, UINT timeout);
+	void (*FreeEvent)(EVENT *event);
+	bool (*WaitThread)(THREAD *t);
+	void (*FreeThread)(THREAD *t);
+	bool (*InitThread)(THREAD *t);
+	UINT (*ThreadId)();
+	void *(*FileOpen)(char *name, bool write_mode, bool read_lock);
+	void *(*FileOpenW)(wchar_t *name, bool write_mode, bool read_lock);
+	void *(*FileCreate)(char *name);
+	void *(*FileCreateW)(wchar_t *name);
+	bool (*FileWrite)(void *pData, void *buf, UINT size);
+	bool (*FileRead)(void *pData, void *buf, UINT size);
+	void (*FileClose)(void *pData, bool no_flush);
+	void (*FileFlush)(void *pData);
+	UINT64 (*FileSize)(void *pData);
+	bool (*FileSeek)(void *pData, UINT mode, int offset);
+	bool (*FileDelete)(char *name);
+	bool (*FileDeleteW)(wchar_t *name);
+	bool (*MakeDir)(char *name);
+	bool (*MakeDirW)(wchar_t *name);
+	bool (*DeleteDir)(char *name);
+	bool (*DeleteDirW)(wchar_t *name);
+	CALLSTACK_DATA *(*GetCallStack)();
+	bool (*GetCallStackSymbolInfo)(CALLSTACK_DATA *s);
+	bool (*FileRename)(char *old_name, char *new_name);
+	bool (*FileRenameW)(wchar_t *old_name, wchar_t *new_name);
+	bool (*Run)(char *filename, char *arg, bool hide, bool wait);
+	bool (*RunW)(wchar_t *filename, wchar_t *arg, bool hide, bool wait);
+	bool (*IsSupportedOs)();
+	void (*GetOsInfo)(OS_INFO *info);
+	void (*Alert)(char *msg, char *caption);
+	void (*AlertW)(wchar_t *msg, wchar_t *caption);
+	char *(*GetProductId)();
+	void (*SetHighPriority)();
+	void (*RestorePriority)();
+	void *(*NewSingleInstance)(char *instance_name);
+	void (*FreeSingleInstance)(void *data);
+	void (*GetMemInfo)(MEMINFO *info);
+	void (*Yield)();
+} OS_DISPATCH_TABLE;
+
+// OS 固有ヘッダのインクルード
+#ifdef	OS_WIN32
+#include <Mayaqua/Win32.h>
+#else	//OS_WIN32
+#include <Mayaqua/Unix.h>
+#endif	// OS_WIN32
+
+#endif	// OS_H
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Object.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Object.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Object.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,525 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Object.c
+// オブジェクト管理コード
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+// 試しにロックをかけてみるスレッド
+void CheckDeadLockThread(THREAD *t, void *param)
+{
+	DEADCHECK *c = (DEADCHECK *)param;
+
+	if (t == NULL || c == NULL)
+	{
+		return;
+	}
+
+	NoticeThreadInit(t);
+
+	Lock(c->Lock);
+	Unlock(c->Lock);
+	c->Unlocked = true;
+}
+
+// デッドロックの検出
+void CheckDeadLock(LOCK *lock, UINT timeout, char *name)
+{
+	DEADCHECK c;
+	THREAD *t;
+	char msg[MAX_PATH];
+
+	if (lock == NULL)
+	{
+		return;
+	}
+	if (name == NULL)
+	{
+		name = "Unknown";
+	}
+
+	Format(msg, sizeof(msg), "error: CheckDeadLock() Failed: %s\n", name);
+
+	Zero(&c, sizeof(c));
+	c.Lock = lock;
+	c.Timeout = timeout;
+	c.Unlocked = false;
+
+	t = NewThread(CheckDeadLockThread, &c);
+	WaitThreadInit(t);
+	if (WaitThread(t, timeout) == false)
+	{
+		if (c.Unlocked == false)
+		{
+			// デッドロック発生
+			AbortExitEx(msg);
+		}
+		else
+		{
+			WaitThread(t, INFINITE);
+		}
+	}
+
+	ReleaseThread(t);
+}
+
+// ロックオブジェクトの作成
+LOCK *NewLockMain()
+{
+	LOCK *lock;
+	UINT retry = 0;
+
+	while (true)
+	{
+		if ((retry++) > OBJECT_ALLOC__MAX_RETRY)
+		{
+			AbortExitEx("error: OSNewLock() failed.\n\n");
+		}
+		lock = OSNewLock();
+		if (lock != NULL)
+		{
+			break;
+		}
+		SleepThread(OBJECT_ALLOC_FAIL_SLEEP_TIME);
+	}
+
+	return lock;
+}
+LOCK *NewLock()
+{
+	LOCK *lock = NewLockMain();
+
+	// KS
+	KS_INC(KS_NEWLOCK_COUNT);
+	KS_INC(KS_CURRENT_LOCK_COUNT);
+
+	return lock;
+}
+
+// ロックオブジェクトの削除
+void DeleteLock(LOCK *lock)
+{
+	// 引数チェック
+	if (lock == NULL)
+	{
+		return;
+	}
+
+	// KS
+	KS_INC(KS_DELETELOCK_COUNT);
+	KS_DEC(KS_CURRENT_LOCK_COUNT);
+
+	OSDeleteLock(lock);
+}
+
+// ロック
+bool LockInner(LOCK *lock)
+{
+	// 引数チェック
+	if (lock == NULL)
+	{
+		return false;
+	}
+
+	// KS
+	KS_INC(KS_LOCK_COUNT);
+	KS_INC(KS_CURRENT_LOCKED_COUNT);
+
+	return OSLock(lock);
+}
+
+// ロック解除
+void UnlockInner(LOCK *lock)
+{
+	// 引数チェック
+	if (lock == NULL)
+	{
+		return;
+	}
+
+	// KS
+	KS_INC(KS_UNLOCK_COUNT);
+	KS_DEC(KS_CURRENT_LOCKED_COUNT);
+
+	OSUnlock(lock);
+}
+
+// カウンタの作成
+COUNTER *NewCounter()
+{
+	COUNTER *c;
+
+	// メモリ確保
+	c = Malloc(sizeof(COUNTER));
+
+	// 初期化
+	c->Ready = true;
+	c->c = 0;
+
+	// ロック作成
+	c->lock = NewLock();
+
+	// KS
+	KS_INC(KS_NEW_COUNTER_COUNT);
+
+	return c;
+}
+
+// カウンタの削除
+void DeleteCounter(COUNTER *c)
+{
+	// 引数チェック
+	if (c == NULL)
+	{
+		return;
+	}
+
+	// KS
+	KS_INC(KS_DELETE_COUNTER_COUNT);
+	KS_SUB(KS_CURRENT_COUNT, c->c);
+
+	DeleteLock(c->lock);
+	Free(c);
+}
+
+// カウント値の取得
+UINT Count(COUNTER *c)
+{
+	UINT ret;
+	// 引数チェック
+	if (c == NULL)
+	{
+		return 0;
+	}
+	if (c->Ready == false)
+	{
+		return 0;
+	}
+
+	Lock(c->lock);
+	{
+		if (c->Ready == false)
+		{
+			ret = 0;
+		}
+		else
+		{
+			ret = c->c;
+		}
+	}
+	Unlock(c->lock);
+
+	return ret;
+}
+
+// インクリメント
+UINT Inc(COUNTER *c)
+{
+	UINT ret;
+	// 引数チェック
+	if (c == NULL)
+	{
+		return 0;
+	}
+	if (c->Ready == false)
+	{
+		return 0;
+	}
+
+	Lock(c->lock);
+	{
+		if (c->Ready == false)
+		{
+			ret = 0;
+		}
+		else
+		{
+			c->c++;
+			ret = c->c;
+		}
+	}
+	Unlock(c->lock);
+
+	// KS
+	KS_INC(KS_INC_COUNT);
+	KS_INC(KS_CURRENT_COUNT);
+
+	return ret;
+}
+
+// デクリメント
+UINT Dec(COUNTER *c)
+{
+	UINT ret;
+	// 引数チェック
+	if (c == NULL)
+	{
+		return 0;
+	}
+	if (c->Ready == false)
+	{
+		return 0;
+	}
+
+	Lock(c->lock);
+	{
+		if (c->Ready == false)
+		{
+			ret = 0;
+		}
+		else
+		{
+			if (c->c != 0)
+			{
+				c->c--;
+				ret = c->c;
+			}
+			else
+			{
+				ret = 0;
+			}
+		}
+	}
+	Unlock(c->lock);
+
+	// KS
+	KS_INC(KS_DEC_COUNT);
+	KS_DEC(KS_CURRENT_COUNT);
+
+	return ret;
+}
+
+
+// 参照カウンタの解放
+UINT Release(REF *ref)
+{
+	UINT c;
+	// 引数チェック
+	if (ref == NULL)
+	{
+		return 0;
+	}
+
+	// KS
+	KS_INC(KS_RELEASE_COUNT);
+	KS_DEC(KS_CURRENT_REFED_COUNT);
+
+	c = Dec(ref->c);
+	if (c == 0)
+	{
+		// KS
+		KS_DEC(KS_CURRENT_REF_COUNT);
+		KS_INC(KS_FREEREF_COUNT);
+
+		DeleteCounter(ref->c);
+		ref->c = 0;
+		Free(ref);
+	}
+	return c;
+}
+
+// 参照カウンタの増加
+UINT AddRef(REF *ref)
+{
+	UINT c;
+	// 引数チェック
+	if (ref == NULL)
+	{
+		return 0;
+	}
+
+	c = Inc(ref->c);
+
+	// KS
+	KS_INC(KS_ADDREF_COUNT);
+	KS_INC(KS_CURRENT_REFED_COUNT);
+
+	return c;
+}
+
+// 参照カウンタ作成
+REF *NewRef()
+{
+	REF *ref;
+
+	// メモリ確保
+	ref = Malloc(sizeof(REF));
+
+	// カウンタ作成
+	ref->c = NewCounter();
+
+	// 1 回だけインクリメント
+	Inc(ref->c);
+
+	// KS
+	KS_INC(KS_NEWREF_COUNT);
+	KS_INC(KS_CURRENT_REF_COUNT);
+	KS_INC(KS_ADDREF_COUNT);
+	KS_INC(KS_CURRENT_REFED_COUNT);
+
+	return ref;
+}
+
+// イベントオブジェクトの作成
+EVENT *NewEvent()
+{
+	// メモリ確保
+	EVENT *e = Malloc(sizeof(EVENT));
+
+	// 参照カウンタ
+	e->ref = NewRef();
+
+	// イベント初期化
+	OSInitEvent(e);
+
+	// KS
+	KS_INC(KS_NEWEVENT_COUNT);
+
+	return e;
+}
+
+// イベントの解放
+void ReleaseEvent(EVENT *e)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return;
+	}
+
+	if (Release(e->ref) == 0)
+	{
+		CleanupEvent(e);
+	}
+}
+
+// イベントの削除
+void CleanupEvent(EVENT *e)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return;
+	}
+
+	// イベント解放
+	OSFreeEvent(e);
+
+	// メモリ解放
+	Free(e);
+
+	// KS
+	KS_INC(KS_FREEEVENT_COUNT);
+}
+
+// イベントのセット
+void Set(EVENT *e)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return;
+	}
+
+	OSSetEvent(e);
+}
+
+// イベントの待機
+bool Wait(EVENT *e, UINT timeout)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return false;
+	}
+
+	// KS
+	KS_INC(KS_WAIT_COUNT);
+
+	return OSWaitEvent(e, timeout);
+}
+
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Object.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Object.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Object.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,181 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Object.h
+// Object.c のヘッダ
+
+#ifndef	OBJECT_H
+#define	OBJECT_H
+
+
+// 定数
+#define	OBJECT_ALLOC_FAIL_SLEEP_TIME		150
+#define	OBJECT_ALLOC__MAX_RETRY				30
+
+// ロックオブジェクト
+struct LOCK
+{
+	void *pData;
+	BOOL Ready;
+#ifdef	OS_UNIX
+	UINT thread_id;
+	UINT locked_count;
+#endif	// OS_UNIX
+#ifdef	_DEBUG
+	char *FileName;
+	UINT Line;
+	UINT ThreadId;
+#endif	// _DEBUG
+};
+
+// カウンタオブジェクト
+struct COUNTER
+{
+	LOCK *lock;
+	UINT c;
+	bool Ready;
+};
+
+// 参照カウンタ
+struct REF
+{
+	COUNTER *c;
+};
+
+// イベントオブジェクト
+struct EVENT
+{
+	REF *ref;
+	void *pData;
+};
+
+// デッドロック検出
+struct DEADCHECK
+{
+	LOCK *Lock;
+	UINT Timeout;
+	bool Unlocked;
+};
+
+
+// ロック関数
+#ifndef	_DEBUG
+
+#define	Lock(lock)		LockInner((lock))
+#define	Unlock(lock)	UnlockInner((lock))
+
+#else	// _DEBUG
+
+#define	Lock(lock)			\
+	{						\
+		LockInner(lock);	\
+		if (lock != NULL) { lock->FileName = __FILE__; lock->Line = __LINE__; lock->ThreadId = ThreadId();}	\
+	}
+
+#define	Unlock(lock)		\
+	{						\
+		if (lock != NULL) { lock->FileName = NULL; lock->Line = 0; lock->ThreadId = 0;}	\
+		UnlockInner(lock);	\
+	}
+
+#endif	// _DEBUG
+
+
+// 関数プロトタイプ
+LOCK *NewLock();
+LOCK *NewLockMain();
+void DeleteLock(LOCK *lock);
+COUNTER *NewCounter();
+void UnlockInner(LOCK *lock);
+bool LockInner(LOCK *lock);
+void DeleteCounter(COUNTER *c);
+UINT Count(COUNTER *c);
+UINT Inc(COUNTER *c);
+UINT Dec(COUNTER *c);
+UINT Release(REF *ref);
+UINT AddRef(REF *ref);
+REF *NewRef();
+EVENT *NewEvent();
+void ReleaseEvent(EVENT *e);
+void CleanupEvent(EVENT *e);
+void Set(EVENT *e);
+bool Wait(EVENT *e, UINT timeout);
+void CheckDeadLock(LOCK *lock, UINT timeout, char *name);
+void CheckDeadLockThread(THREAD *t, void *param);
+
+#endif	// OBJECT_H
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Pack.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Pack.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Pack.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,815 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Pack.c
+// データパッケージコード
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+// BUF を PACK に変換
+PACK *BufToPack(BUF *b)
+{
+	PACK *p;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	p = NewPack();
+	if (ReadPack(b, p) == false)
+	{
+		FreePack(p);
+		return NULL;
+	}
+
+	return p;
+}
+
+// PACK を BUF に変換
+BUF *PackToBuf(PACK *p)
+{
+	BUF *b;
+	// 引数チェック
+	if (p == NULL)
+	{
+		return NULL;
+	}
+
+	b = NewBuf();
+	WritePack(b, p);
+
+	return b;
+}
+
+// PACK を読み込む
+bool ReadPack(BUF *b, PACK *p)
+{
+	UINT i, num;
+	// 引数チェック
+	if (b == NULL || p == NULL)
+	{
+		return false;
+	}
+
+	// ELEMENT 数
+	num = ReadBufInt(b);
+	if (num > MAX_ELEMENT_NUM)
+	{
+		// 個数オーバー
+		return false;
+	}
+
+	// ELEMENT を読み込む
+	for (i = 0;i < num;i++)
+	{
+		ELEMENT *e;
+		e = ReadElement(b);
+		if (AddElement(p, e) == false)
+		{
+			// 追加エラー
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// PACK を書き出す
+void WritePack(BUF *b, PACK *p)
+{
+	UINT i;
+	// 引数チェック
+	if (b == NULL || p == NULL)
+	{
+		return;
+	}
+
+	// ELEMENT 数
+	WriteBufInt(b, LIST_NUM(p->elements));
+
+	// ELEMENT を書き出す
+	for (i = 0;i < LIST_NUM(p->elements);i++)
+	{
+		ELEMENT *e = LIST_DATA(p->elements, i);
+		WriteElement(b, e);
+	}
+}
+
+// ELEMENT を読み込む
+ELEMENT *ReadElement(BUF *b)
+{
+	UINT i;
+	char name[MAX_ELEMENT_NAME_LEN + 1];
+	UINT type, num_value;
+	VALUE **values;
+	ELEMENT *e;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	// 名前
+	if (ReadBufStr(b, name, sizeof(name)) == false)
+	{
+		return NULL;
+	}
+
+	// 項目の種類
+	type = ReadBufInt(b);
+
+	// 項目数
+	num_value = ReadBufInt(b);
+	if (num_value > MAX_VALUE_NUM)
+	{
+		// 個数オーバー
+		return NULL;
+	}
+
+	// VALUE
+	values = (VALUE **)Malloc(sizeof(VALUE *) * num_value);
+	for (i = 0;i < num_value;i++)
+	{
+		values[i] = ReadValue(b, type);
+	}
+
+	// ELEMENT を作成
+	e = NewElement(name, type, num_value, values);
+
+	Free(values);
+
+	return e;
+}
+
+// ELEMENT を書き出す
+void WriteElement(BUF *b, ELEMENT *e)
+{
+	UINT i;
+	// 引数チェック
+	if (b == NULL || e == NULL)
+	{
+		return;
+	}
+
+	// 名前
+	WriteBufStr(b, e->name);
+	// 項目の種類
+	WriteBufInt(b, e->type);
+	// 項目数
+	WriteBufInt(b, e->num_value);
+	// VALUE
+	for (i = 0;i < e->num_value;i++)
+	{
+		VALUE *v = e->values[i];
+		WriteValue(b, v, e->type);
+	}
+}
+
+// VALUE を読み込む
+VALUE *ReadValue(BUF *b, UINT type)
+{
+	UINT len;
+	BYTE *u;
+	void *data;
+	char *str;
+	wchar_t *unistr;
+	UINT unistr_size;
+	UINT size;
+	UINT u_size;
+	VALUE *v = NULL;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	// データ項目
+	switch (type)
+	{
+	case VALUE_INT:			// 整数
+		v = NewIntValue(ReadBufInt(b));
+		break;
+	case VALUE_INT64:
+		v = NewInt64Value(ReadBufInt64(b));
+		break;
+	case VALUE_DATA:		// データ
+		size = ReadBufInt(b);
+		if (size > MAX_VALUE_SIZE)
+		{
+			// サイズオーバー
+			break;
+		}
+		data = Malloc(size);
+		if (ReadBuf(b, data, size) != size)
+		{
+			// 読み込み失敗
+			Free(data);
+			break;
+		}
+		v = NewDataValue(data, size);
+		Free(data);
+		break;
+	case VALUE_STR:			// ANSI 文字列
+		len = ReadBufInt(b);
+		if ((len + 1) > MAX_VALUE_SIZE)
+		{
+			// サイズオーバー
+			break;
+		}
+		str = Malloc(len + 1);
+		// 文字列本体
+		if (ReadBuf(b, str, len) != len)
+		{
+			// 読み込み失敗
+			Free(str);
+			break;
+		}
+		str[len] = 0;
+		v = NewStrValue(str);
+		Free(str);
+		break;
+	case VALUE_UNISTR:		// Unicode 文字列
+		u_size = ReadBufInt(b);
+		if (u_size > MAX_VALUE_SIZE)
+		{
+			// サイズオーバー
+			break;
+		}
+		// UTF-8 の読み込み
+		u = ZeroMalloc(u_size + 1);
+		if (ReadBuf(b, u, u_size) != u_size)
+		{
+			// 読み込み失敗
+			Free(u);
+			break;
+		}
+		// Unicode 文字列に変換
+		unistr_size = CalcUtf8ToUni(u, u_size);
+		if (unistr_size == 0)
+		{
+			Free(u);
+			break;
+		}
+		unistr = Malloc(unistr_size);
+		Utf8ToUni(unistr, unistr_size, u, u_size);
+		Free(u);
+		v = NewUniStrValue(unistr);
+		Free(unistr);
+		break;
+	}
+
+	return v;
+}
+
+// VALUE を書き出す
+void WriteValue(BUF *b, VALUE *v, UINT type)
+{
+	UINT len;
+	BYTE *u;
+	UINT u_size;
+	// 引数チェック
+	if (b == NULL || v == NULL)
+	{
+		return;
+	}
+
+	// データ項目
+	switch (type)
+	{
+	case VALUE_INT:			// 整数
+		WriteBufInt(b, v->IntValue);
+		break;
+	case VALUE_INT64:		// 64 bit 整数
+		WriteBufInt64(b, v->Int64Value);
+		break;
+	case VALUE_DATA:		// データ
+		// サイズ
+		WriteBufInt(b, v->Size);
+		// 本体
+		WriteBuf(b, v->Data, v->Size);
+		break;
+	case VALUE_STR:			// ANSI 文字列
+		len = StrLen(v->Str);
+		// 長さ
+		WriteBufInt(b, len);
+		// 文字列本体
+		WriteBuf(b, v->Str, len);
+		break;
+	case VALUE_UNISTR:		// Unicode 文字列
+		// UTF-8 に変換する
+		u_size = CalcUniToUtf8(v->UniStr) + 1;
+		u = ZeroMalloc(u_size);
+		UniToUtf8(u, u_size, v->UniStr);
+		// サイズ
+		WriteBufInt(b, u_size);
+		// UTF-8 文字列本体
+		WriteBuf(b, u, u_size);
+		Free(u);
+		break;
+	}
+}
+
+// データサイズの取得
+UINT GetDataValueSize(ELEMENT *e, UINT index)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return 0;
+	}
+	if (e->values == NULL)
+	{
+		return 0;
+	}
+	if (index >= e->num_value)
+	{
+		return 0;
+	}
+	if (e->values[index] == NULL)
+	{
+		return 0;
+	}
+
+	return e->values[index]->Size;
+}
+
+// データの取得
+void *GetDataValue(ELEMENT *e, UINT index)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return NULL;
+	}
+	if (e->values == NULL)
+	{
+		return NULL;
+	}
+	if (index >= e->num_value)
+	{
+		return NULL;
+	}
+	if (e->values[index] == NULL)
+	{
+		return NULL;
+	}
+
+	return e->values[index]->Data;
+}
+
+// Unicode 文字列型の取得
+wchar_t *GetUniStrValue(ELEMENT *e, UINT index)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return 0;
+	}
+	if (index >= e->num_value)
+	{
+		return 0;
+	}
+
+	return e->values[index]->UniStr;
+}
+
+// ANSI 文字列型の取得
+char *GetStrValue(ELEMENT *e, UINT index)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return 0;
+	}
+	if (index >= e->num_value)
+	{
+		return 0;
+	}
+
+	return e->values[index]->Str;
+}
+
+// 64 bit 整数型値の取得
+UINT64 GetInt64Value(ELEMENT *e, UINT index)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return 0;
+	}
+	if (index >= e->num_value)
+	{
+		return 0;
+	}
+
+	return e->values[index]->Int64Value;
+}
+
+// 整数型値の取得
+UINT GetIntValue(ELEMENT *e, UINT index)
+{
+	// 引数チェック
+	if (e == NULL)
+	{
+		return 0;
+	}
+	if (index >= e->num_value)
+	{
+		return 0;
+	}
+
+	return e->values[index]->IntValue;
+}
+
+// PACK のソート関数
+int ComparePackName(void *p1, void *p2)
+{
+	ELEMENT *o1, *o2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	o1 = *(ELEMENT **)p1;
+	o2 = *(ELEMENT **)p2;
+	if (o1 == NULL || o2 == NULL)
+	{
+		return 0;
+	}
+
+	return StrCmpi(o1->name, o2->name);
+}
+
+// VALUE の削除
+void FreeValue(VALUE *v, UINT type)
+{
+	// 引数チェック
+	if (v == NULL)
+	{
+		return;
+	}
+
+	switch (type)
+	{
+	case VALUE_INT:
+	case VALUE_INT64:
+		break;
+	case VALUE_DATA:
+		Free(v->Data);
+		break;
+	case VALUE_STR:
+		Free(v->Str);
+		break;
+	case VALUE_UNISTR:
+		Free(v->UniStr);
+		break;
+	}
+
+	// メモリ解放
+	Free(v);
+}
+
+// Unicode 文字列型の VALUE の作成
+VALUE *NewUniStrValue(wchar_t *str)
+{
+	VALUE *v;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	// メモリ確保
+	v = Malloc(sizeof(VALUE));
+
+	// 文字列コピー
+	v->Size = UniStrSize(str);
+	v->UniStr = Malloc(v->Size);
+	UniStrCpy(v->UniStr, v->Size, str);
+
+	UniTrim(v->UniStr);
+
+	return v;
+}
+
+// ANSI 文字列型の VALUE の作成
+VALUE *NewStrValue(char *str)
+{
+	VALUE *v;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	// メモリ確保
+	v = Malloc(sizeof(VALUE));
+
+	// 文字列コピー
+	v->Size = StrLen(str) + 1;
+	v->Str = Malloc(v->Size);
+	StrCpy(v->Str, v->Size, str);
+
+	Trim(v->Str);
+
+	return v;
+}
+
+// データ型の VALUE の作成
+VALUE *NewDataValue(void *data, UINT size)
+{
+	VALUE *v;
+	// 引数チェック
+	if (data == NULL)
+	{
+		return NULL;
+	}
+
+	// メモリ確保
+	v = Malloc(sizeof(VALUE));
+
+	// データコピー
+	v->Size = size;
+	v->Data = Malloc(v->Size);
+	Copy(v->Data, data, size);
+
+	return v;
+}
+
+// 64 bit 整数型の VALUE の作成
+VALUE *NewInt64Value(UINT64 i)
+{
+	VALUE *v;
+
+	v = Malloc(sizeof(VALUE));
+	v->Int64Value = i;
+	v->Size = sizeof(UINT64);
+
+	return v;
+}
+
+// 整数型の VALUE の作成
+VALUE *NewIntValue(UINT i)
+{
+	VALUE *v;
+
+	// メモリ確保
+	v = Malloc(sizeof(VALUE));
+	v->IntValue = i;
+	v->Size = sizeof(UINT);
+
+	return v;
+}
+
+// ELEMENT の削除
+void FreeElement(ELEMENT *e)
+{
+	UINT i;
+	// 引数チェック
+	if (e == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < e->num_value;i++)
+	{
+		FreeValue(e->values[i], e->type);
+	}
+	Free(e->values);
+
+	Free(e);
+}
+
+// ELEMENT の作成
+ELEMENT *NewElement(char *name, UINT type, UINT num_value, VALUE **values)
+{
+	ELEMENT *e;
+	UINT i;
+	// 引数チェック
+	if (name == NULL || num_value == 0 || values == NULL)
+	{
+		return NULL;
+	}
+
+	// メモリ確保
+	e = Malloc(sizeof(ELEMENT));
+	StrCpy(e->name, sizeof(e->name), name);
+	e->num_value = num_value;
+	e->type = type;
+
+	// 要素へのポインタリストのコピー
+	e->values = (VALUE **)Malloc(sizeof(VALUE *) * num_value);
+	for (i = 0;i < e->num_value;i++)
+	{
+		e->values[i] = values[i];
+	}
+
+	return e;
+}
+
+// PACK から ELEMENT を検索して取得
+ELEMENT *GetElement(PACK *p, char *name, UINT type)
+{
+	ELEMENT t;
+	ELEMENT *e;
+	// 引数チェック
+	if (p == NULL || name == NULL)
+	{
+		return NULL;
+	}
+
+	// 検索
+	StrCpy(t.name, sizeof(t.name), name);
+	e = Search(p->elements, &t);
+
+	if (e == NULL)
+	{
+		return NULL;
+	}
+
+	// 型検査
+	if (type != INFINITE)
+	{
+		if (e->type != type)
+		{
+			return NULL;
+		}
+	}
+
+	return e;
+}
+
+// PACK から ELEMENT を削除
+void DelElement(PACK *p, char *name)
+{
+	ELEMENT *e;
+	// 引数チェック
+	if (p == NULL || name == NULL)
+	{
+		return;
+	}
+
+	e = GetElement(p, name, INFINITE);
+	if (e != NULL)
+	{
+		Delete(p->elements, e);
+
+		FreeElement(e);
+	}
+}
+
+// PACK に ELEMENT を追加
+bool AddElement(PACK *p, ELEMENT *e)
+{
+	// 引数チェック
+	if (p == NULL || e == NULL)
+	{
+		return false;
+	}
+
+	// サイズチェック
+	if (LIST_NUM(p->elements) >= MAX_ELEMENT_NUM)
+	{
+		// これ以上追加できない
+		FreeElement(e);
+		return false;
+	}
+
+	// 同じ名前が存在しないかどうかチェック
+	if (GetElement(p, e->name, INFINITE))
+	{
+		// 存在している
+		FreeElement(e);
+		return false;
+	}
+
+	if (e->num_value == 0)
+	{
+		// 項目が 1 つも存在していない VALUE は追加できない
+		FreeElement(e);
+		return false;
+	}
+
+	// 追加
+	Add(p->elements, e);
+	return true;
+}
+
+// PACK オブジェクトの解放
+void FreePack(PACK *p)
+{
+	UINT i;
+	ELEMENT **elements;
+	// 引数チェック
+	if (p == NULL)
+	{
+		return;
+	}
+
+	elements = ToArray(p->elements);
+	for (i = 0;i < LIST_NUM(p->elements);i++)
+	{
+		FreeElement(elements[i]);
+	}
+	Free(elements);
+
+	ReleaseList(p->elements);
+	Free(p);
+}
+
+// PACK オブジェクトの作成
+PACK *NewPack()
+{
+	PACK *p;
+
+	// メモリ確保
+	p = MallocEx(sizeof(PACK), true);
+
+	// リスト作成
+	p->elements = NewListFast(ComparePackName);
+
+	return p;
+}
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Pack.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Pack.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Pack.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,170 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Pack.h
+// Pack.c のヘッダ
+
+#ifndef	PACK_H
+#define	PACK_H
+
+// 定数
+#ifdef CPU_64
+
+#define	MAX_VALUE_SIZE			(384 * 1024 * 1024)	// 1 つの VALUE に格納できるデータサイズ
+#define	MAX_VALUE_NUM			262144	// 1 つの ELEMENT に格納できる最大 VALUE 数
+#define	MAX_ELEMENT_NAME_LEN	63		// ELEMENT に付けることのできる名前の長さ
+#define	MAX_ELEMENT_NUM			262144	// 1 つの PACK に格納できる最大 ELEMENT 数
+#define	MAX_PACK_SIZE			(512 * 1024 * 1024)	// シリアル化された PACK の最大サイズ
+
+#else	// CPU_64
+
+#define	MAX_VALUE_SIZE			(96 * 1024 * 1024)	// 1 つの VALUE に格納できるデータサイズ
+#define	MAX_VALUE_NUM			65536	// 1 つの ELEMENT に格納できる最大 VALUE 数
+#define	MAX_ELEMENT_NAME_LEN	63		// ELEMENT に付けることのできる名前の長さ
+#define	MAX_ELEMENT_NUM			131072	// 1 つの PACK に格納できる最大 ELEMENT 数
+#define	MAX_PACK_SIZE			(128 * 1024 * 1024)	// シリアル化された PACK の最大サイズ
+
+#endif	// CPU_64
+
+// VALUE の種類
+#define	VALUE_INT			0		// 整数型
+#define	VALUE_DATA			1		// データ型
+#define	VALUE_STR			2		// ANSI 文字列型
+#define	VALUE_UNISTR		3		// Unicode 文字列型
+#define	VALUE_INT64			4		// 64 bit 整数型
+
+// VALUE オブジェクト
+struct VALUE
+{
+	UINT Size;				// サイズ
+	UINT IntValue;			// 整数値
+	void *Data;				// データ
+	char *Str;				// ANSI 文字列
+	wchar_t *UniStr;		// Unicode 文字列
+	UINT64 Int64Value;		// 64 bit 整数型
+};
+
+// ELEMENT オブジェクト
+struct ELEMENT
+{
+	char name[MAX_ELEMENT_NAME_LEN + 1];	// 要素名
+	UINT num_value;			// 値の数 (>=1)
+	UINT type;				// 型
+	VALUE **values;			// 値へのポインタのリスト
+};
+
+// PACK オブジェクト
+struct PACK
+{
+	LIST *elements;			// 要素リスト
+};
+
+
+// 関数プロトタイプ
+PACK *NewPack();
+bool AddElement(PACK *p, ELEMENT *e);
+void DelElement(PACK *p, char *name);
+ELEMENT *GetElement(PACK *p, char *name, UINT type);
+void FreePack(PACK *p);
+ELEMENT *NewElement(char *name, UINT type, UINT num_value, VALUE **values);
+VALUE *NewIntValue(UINT i);
+VALUE *NewDataValue(void *data, UINT size);
+VALUE *NewStrValue(char *str);
+VALUE *NewUniStrValue(wchar_t *str);
+void FreeValue(VALUE *v, UINT type);
+int ComparePackName(void *p1, void *p2);
+void FreeElement(ELEMENT *e);
+UINT GetValueNum(ELEMENT *e);
+UINT GetIntValue(ELEMENT *e, UINT index);
+UINT64 GetInt64Value(ELEMENT *e, UINT index);
+char *GetStrValue(ELEMENT *e, UINT index);
+wchar_t *GetUniStrValue(ELEMENT *e, UINT index);
+UINT GetDataValueSize(ELEMENT *e, UINT index);
+void *GetDataValue(ELEMENT *e, UINT index);
+BUF *PackToBuf(PACK *p);
+void WritePack(BUF *b, PACK *p);
+void WriteElement(BUF *b, ELEMENT *e);
+void WriteValue(BUF *b, VALUE *v, UINT type);
+PACK *BufToPack(BUF *b);
+bool ReadPack(BUF *b, PACK *p);
+ELEMENT *ReadElement(BUF *b);
+VALUE *ReadValue(BUF *b, UINT type);
+void Bit160ToStr(char *str, UCHAR *data);
+void Bit128ToStr(char *str, UCHAR *data);
+VALUE *NewInt64Value(UINT64 i);
+
+#endif	// PACK_H
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Secure.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Secure.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Secure.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,2188 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Secure.c
+// セキュリティトークン管理モジュール
+
+#define	SECURE_C
+#define	ENCRYPT_C
+
+#ifdef	WIN32
+#include <windows.h>
+#endif	// WIN32
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/engine.h>
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rc4.h>
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+#include <Mayaqua/Mayaqua.h>
+#include <Mayaqua/cryptoki.h>
+
+
+#define	MAX_OBJ				1024		// ハードウェア内の最大オブジェクト数 (想定)
+
+#define	A_SIZE(a, i)		(a[(i)].ulValueLen)
+#define	A_SET(a, i, value, size)	(a[i].pValue = value;a[i].ulValueLen = size;)
+
+#ifdef	OS_WIN32
+// Win32 用コード
+
+// Win32 用 DLL 読み込み
+HINSTANCE Win32SecureLoadLibraryEx(char *dllname, DWORD flags)
+{
+	char tmp1[MAX_PATH];
+	char tmp2[MAX_PATH];
+	char tmp3[MAX_PATH];
+	HINSTANCE h;
+	// 引数チェック
+	if (dllname == NULL)
+	{
+		return NULL;
+	}
+
+	Format(tmp1, sizeof(tmp1), "%s\\%s", MsGetSystem32Dir(), dllname);
+	Format(tmp2, sizeof(tmp2), "%s\\JPKI\\%s", MsGetProgramFilesDir(), dllname);
+	Format(tmp3, sizeof(tmp3), "%s\\LGWAN\\%s", MsGetProgramFilesDir(), dllname);
+
+	h = LoadLibraryEx(dllname, NULL, flags);
+	if (h != NULL)
+	{
+		return h;
+	}
+
+	h = LoadLibraryEx(tmp1, NULL, flags);
+	if (h != NULL)
+	{
+		return h;
+	}
+
+	h = LoadLibraryEx(tmp2, NULL, flags);
+	if (h != NULL)
+	{
+		return h;
+	}
+
+	h = LoadLibraryEx(tmp3, NULL, flags);
+	if (h != NULL)
+	{
+		return h;
+	}
+
+	return NULL;
+}
+
+// 指定したデバイスがインストールされているか調査
+bool Win32IsDeviceSupported(SECURE_DEVICE *dev)
+{
+	HINSTANCE hInst;
+	// 引数チェック
+	if (dev == NULL)
+	{
+		return false;
+	}
+
+	// DLL が読み込み可能かチェック
+	hInst = Win32SecureLoadLibraryEx(dev->ModuleName, DONT_RESOLVE_DLL_REFERENCES);
+	if (hInst == NULL)
+	{
+		return false;
+	}
+
+	FreeLibrary(hInst);
+
+	return true;
+}
+
+// デバイスモジュールの読み込み
+bool Win32LoadSecModule(SECURE *sec)
+{
+	SEC_DATA_WIN32 *w;
+	HINSTANCE hInst;
+	CK_FUNCTION_LIST_PTR api = NULL;
+	CK_RV (*get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+
+	if (sec->Dev->Id == 9)
+	{
+		char username[MAX_SIZE];
+		DWORD size;
+		// 住基ネットのデバイスドライバでは、Software\JPKI レジストリキーの内容を
+		// SYSTEM の HKLU でも持っていなければならないので、もし持っていない場合は
+		// 別のユーザーの値からコピーする
+//		if (MsRegIsValue(REG_CURRENT_USER, "Software\\JPKI", "Name") == false ||
+//			MsRegIsValue(REG_CURRENT_USER, "Software\\JPKI", "RWType") == false)
+		size = sizeof(username);
+		GetUserName(username, &size);
+		if (StrCmpi(username, "System") == 0)
+		{
+			TOKEN_LIST *t = MsRegEnumKey(REG_USERS, NULL);
+
+			if (t != NULL)
+			{
+				UINT i;
+
+				for (i = 0;i < t->NumTokens;i++)
+				{
+					char tmp[MAX_PATH];
+
+					if (StrCmpi(t->Token[i], ".DEFAULT") != 0 && StrCmpi(t->Token[i], "S-1-5-18") != 0)
+					{
+						Format(tmp, sizeof(tmp), "%s\\Software\\JPKI", t->Token[i]);
+
+						if (MsRegIsValue(REG_USERS, tmp, "Name") && MsRegIsValue(REG_USERS, tmp, "RWType"))
+						{
+							char *name = MsRegReadStr(REG_USERS, tmp, "Name");
+							char *port = MsRegReadStr(REG_USERS, tmp, "Port");
+							UINT type = MsRegReadInt(REG_USERS, tmp, "RWType");
+
+							MsRegWriteStr(REG_CURRENT_USER, "Software\\JPKI", "Name", name);
+							MsRegWriteStr(REG_CURRENT_USER, "Software\\JPKI", "Port", port);
+							MsRegWriteInt(REG_CURRENT_USER, "Software\\JPKI", "RWType", type);
+
+							Free(name);
+							Free(port);
+							break;
+						}
+					}
+				}
+
+				FreeToken(t);
+			}
+		}
+	}
+
+	// ライブラリのロード
+	hInst = Win32SecureLoadLibraryEx(sec->Dev->ModuleName, 0);
+	if (hInst == NULL)
+	{
+		// 失敗
+		return false;
+	}
+
+	// API の取得
+	get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR))
+		GetProcAddress(hInst, "C_GetFunctionList");
+
+	if (get_function_list == NULL)
+	{
+		// 失敗
+		FreeLibrary(hInst);
+		return false;
+	}
+
+	get_function_list(&api);
+	if (api == NULL)
+	{
+		// 失敗
+		FreeLibrary(hInst);
+		return false;
+	}
+
+	sec->Data = ZeroMalloc(sizeof(SEC_DATA_WIN32));
+	w = sec->Data;
+
+	w->hInst = hInst;
+	sec->Api = api;
+
+	return true;
+}
+
+// デバイスモジュールのアンロード
+void Win32FreeSecModule(SECURE *sec)
+{
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return;
+	}
+	if (sec->Data == NULL)
+	{
+		return;
+	}
+
+	// アンロード
+	FreeLibrary(sec->Data->hInst);
+	Free(sec->Data);
+
+	sec->Data = NULL;
+}
+
+#endif	// OS_WIN32
+
+
+// 指定されたデバイスが JPKI かどうか
+bool IsJPKI(bool id)
+{
+	if (id == 9 || id == 13)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// セキュアデバイスの秘密鍵を名前を指定して署名
+bool SignSec(SECURE *sec, char *name, void *dst, void *src, UINT size)
+{
+	SEC_OBJ *obj;
+	UINT ret;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (name == NULL || dst == NULL || src == NULL)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+
+	obj = FindSecObject(sec, name, SEC_K);
+	if (obj == NULL)
+	{
+		return false;
+	}
+
+	ret = SignSecByObject(sec, obj, dst, src, size);
+
+	FreeSecObject(obj);
+
+	return ret;
+}
+
+// セキュアデバイスの秘密鍵で署名
+bool SignSecByObject(SECURE *sec, SEC_OBJ *obj, void *dst, void *src, UINT size)
+{
+	CK_MECHANISM mechanism = {CKM_RSA_PKCS, NULL, 0};
+	UINT ret;
+	UCHAR hash[SIGN_HASH_SIZE];
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (obj == NULL || dst == NULL || src == NULL)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+	}
+	if (sec->LoginFlag == false && obj->Private)
+	{
+		sec->Error = SEC_ERROR_NOT_LOGIN;
+		return false;
+	}
+	if (obj->Type != SEC_K)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+
+	// ハッシュ
+	HashForSign(hash, sizeof(hash), src, size);
+
+	// 署名初期化
+	ret = sec->Api->C_SignInit(sec->SessionId, &mechanism, obj->Object);
+	if (ret != CKR_OK)
+	{
+		// 失敗
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		Debug("C_SignInit Error: 0x%x\n", ret);
+		return false;
+	}
+
+	// 署名実行
+	size = 128;
+	ret = sec->Api->C_Sign(sec->SessionId, hash, sizeof(hash), dst, &size);
+	if (ret != CKR_OK || size != 128)
+	{
+		// 失敗
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		Debug("C_Sign Error: 0x%x\n", ret);
+		return false;
+	}
+
+	return true;
+}
+
+// PIN コードの変更
+bool ChangePin(SECURE *sec, char *old_pin, char *new_pin)
+{
+	// 引数チェック
+	if (sec == NULL || old_pin == NULL || new_pin == NULL)
+	{
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+	}
+	if (sec->LoginFlag == false)
+	{
+		sec->Error = SEC_ERROR_NOT_LOGIN;
+		return false;
+	}
+	if (sec->IsReadOnly)
+	{
+		sec->Error = SEC_ERROR_OPEN_SESSION;
+		return false;
+	}
+
+	// PIN 変更
+	if (sec->Api->C_SetPIN(sec->SessionId, old_pin, StrLen(old_pin),
+		new_pin, StrLen(new_pin)) != CKR_OK)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// 秘密鍵オブジェクトの書き込み
+bool WriteSecKey(SECURE *sec, bool private_obj, char *name, K *k)
+{
+	UINT key_type = CKK_RSA;
+	CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
+	UINT obj_class = CKO_PRIVATE_KEY;
+	UINT object;
+	UINT ret;
+	BUF *b;
+	RSA *rsa;
+	UCHAR modules[MAX_SIZE], pub[MAX_SIZE], pri[MAX_SIZE], prime1[MAX_SIZE], prime2[MAX_SIZE];
+	CK_ATTRIBUTE a[] =
+	{
+		{CKA_MODULUS,			modules,		0},		// 0
+		{CKA_PUBLIC_EXPONENT,	pub,			0},		// 1
+		{CKA_PRIVATE_EXPONENT,	pri,			0},		// 2
+		{CKA_PRIME_1,			prime1,			0},		// 3
+		{CKA_PRIME_2,			prime2,			0},		// 4
+		{CKA_CLASS,				&obj_class,		sizeof(obj_class)},
+		{CKA_TOKEN,				&b_true,		sizeof(b_true)},
+		{CKA_PRIVATE,			&b_private_obj,	sizeof(b_private_obj)},
+		{CKA_LABEL,				name,			StrLen(name)},
+		{CKA_KEY_TYPE,			&key_type,		sizeof(key_type)},
+		{CKA_DERIVE,			&b_false,		sizeof(b_false)},
+		{CKA_SUBJECT,			name,			StrLen(name)},
+		{CKA_SENSITIVE,			&b_true,		sizeof(b_true)},
+		{CKA_DECRYPT,			&b_true,		sizeof(b_true)},
+		{CKA_SIGN,				&b_true,		sizeof(b_true)},
+		{CKA_SIGN_RECOVER,		&b_false,		sizeof(b_false)},
+		{CKA_EXTRACTABLE,		&b_false,		sizeof(b_false)},
+		{CKA_MODIFIABLE,		&b_false,		sizeof(b_false)},
+	};
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (name == NULL || k == NULL || k->private_key == false)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+	}
+	if (sec->LoginFlag == false && private_obj)
+	{
+		sec->Error = SEC_ERROR_NOT_LOGIN;
+		return false;
+	}
+
+	// 数値データ生成
+	rsa = k->pkey->pkey.rsa;
+	if (rsa == NULL)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+	b = BigNumToBuf(rsa->n);
+	ReadBuf(b, modules, sizeof(modules));
+	A_SIZE(a, 0) = b->Size;
+	FreeBuf(b);
+
+	b = BigNumToBuf(rsa->e);
+	ReadBuf(b, pub, sizeof(pub));
+	A_SIZE(a, 1) = b->Size;
+	FreeBuf(b);
+
+	b = BigNumToBuf(rsa->d);
+	ReadBuf(b, pri, sizeof(pri));
+	A_SIZE(a, 2) = b->Size;
+	FreeBuf(b);
+
+	b = BigNumToBuf(rsa->p);
+	ReadBuf(b, prime1, sizeof(prime1));
+	A_SIZE(a, 3) = b->Size;
+	FreeBuf(b);
+
+	b = BigNumToBuf(rsa->q);
+	ReadBuf(b, prime2, sizeof(prime2));
+	A_SIZE(a, 4) = b->Size;
+	FreeBuf(b);
+
+	// 古い鍵があれば削除
+	if (CheckSecObject(sec, name, SEC_K))
+	{
+		DeleteSecKey(sec, name);
+	}
+
+	// 作成
+	if ((ret = sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object)) != CKR_OK)
+	{
+		// 失敗
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		Debug("ret: 0x%x\n", ret);
+		return false;
+	}
+
+	// キャッシュ消去
+	EraseEnumSecObjectCache(sec);
+
+	return true;
+}
+
+// 証明書オブジェクトを名前を指定して読み込み
+X *ReadSecCert(SECURE *sec, char *name)
+{
+	SEC_OBJ *obj;
+	X *x;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+	}
+
+	// 検索
+	obj = FindSecObject(sec, name, SEC_X);
+	if (obj == NULL)
+	{
+		return false;
+	}
+
+	// 取得
+	x = ReadSecCertFromObject(sec, obj);
+
+	FreeSecObject(obj);
+
+	return x;
+}
+
+// 証明書オブジェクトの読み込み
+X *ReadSecCertFromObject(SECURE *sec, SEC_OBJ *obj)
+{
+	UINT size;
+	X *x;
+	UCHAR value[4096];
+	BUF *b;
+	CK_ATTRIBUTE get[] =
+	{
+		{CKA_VALUE,		value,		sizeof(value)},
+	};
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+	}
+	if (sec->LoginFlag == false && obj->Private)
+	{
+		sec->Error = SEC_ERROR_NOT_LOGIN;
+		return false;
+	}
+	if (obj->Type != SEC_X)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+
+	// 取得
+	if (sec->Api->C_GetAttributeValue(
+		sec->SessionId, obj->Object, get, sizeof(get) / sizeof(get[0])) != CKR_OK)
+	{
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		return 0;
+	}
+
+	size = A_SIZE(get, 0);
+
+	// 変換
+	b = NewBuf();
+	WriteBuf(b, value, size);
+	SeekBuf(b, 0, 0);
+
+	x = BufToX(b, false);
+	if (x == NULL)
+	{
+		sec->Error = SEC_ERROR_INVALID_CERT;
+	}
+
+	FreeBuf(b);
+
+	return x;
+}
+
+// 証明書オブジェクトの書き込み
+bool WriteSecCert(SECURE *sec, bool private_obj, char *name, X *x)
+{
+	UINT obj_class = CKO_CERTIFICATE;
+	CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
+	UINT cert_type = CKC_X_509;
+	CK_DATE start_date, end_date;
+	UCHAR subject[MAX_SIZE];
+	UCHAR issuer[MAX_SIZE];
+	wchar_t w_subject[MAX_SIZE];
+	wchar_t w_issuer[MAX_SIZE];
+	UCHAR serial_number[MAX_SIZE];
+	UCHAR value[4096];
+	UINT ret;
+	BUF *b;
+	UINT object;
+	CK_ATTRIBUTE a[] =
+	{
+		{CKA_SUBJECT,			subject,		0},			// 0
+		{CKA_ISSUER,			issuer,			0},			// 1
+		{CKA_SERIAL_NUMBER,		serial_number,	0},			// 2
+		{CKA_VALUE,				value,			0},			// 3
+		{CKA_CLASS,				&obj_class,		sizeof(obj_class)},
+		{CKA_TOKEN,				&b_true,		sizeof(b_true)},
+		{CKA_PRIVATE,			&b_private_obj,	sizeof(b_private_obj)},
+		{CKA_LABEL,				name,			StrLen(name)},
+		{CKA_CERTIFICATE_TYPE,	&cert_type,		sizeof(cert_type)},
+#if	0		// 失敗するトークンがあるのでこれは使わない
+		{CKA_START_DATE,		&start_date,	sizeof(start_date)},
+		{CKA_END_DATE,			&end_date,		sizeof(end_date)},
+#endif
+	};
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (name == NULL)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+	}
+	if (sec->LoginFlag == false && private_obj)
+	{
+		sec->Error = SEC_ERROR_NOT_LOGIN;
+		return false;
+	}
+
+	// 証明書をバッファにコピー
+	b = XToBuf(x, false);
+	if (b == NULL)
+	{
+		sec->Error = SEC_ERROR_INVALID_CERT;
+		return false;
+	}
+	if (b->Size > sizeof(value))
+	{
+		// サイズが大きすぎる
+		FreeBuf(b);
+		sec->Error = SEC_ERROR_DATA_TOO_BIG;
+		return false;
+	}
+	Copy(value, b->Buf, b->Size);
+	A_SIZE(a, 3) = b->Size;
+	FreeBuf(b);
+
+	// Subject と Issuer を UTF-8 にエンコードして格納
+	GetPrintNameFromName(w_subject, sizeof(w_subject), x->subject_name);
+	UniToUtf8(subject, sizeof(subject), w_subject);
+	A_SIZE(a, 0) = StrLen(subject);
+	if (x->root_cert == false)
+	{
+		GetPrintNameFromName(w_issuer, sizeof(w_issuer), x->issuer_name);
+		UniToUtf8(issuer, sizeof(issuer), w_issuer);
+		A_SIZE(a, 1) = StrLen(issuer);
+	}
+
+	// シリアル番号をコピー
+	Copy(serial_number, x->serial->data, MIN(x->serial->size, sizeof(serial_number)));
+	A_SIZE(a, 2) = MIN(x->serial->size, sizeof(serial_number));
+
+	// 有効期限情報
+	UINT64ToCkDate(&start_date, SystemToLocal64(x->notBefore));
+	UINT64ToCkDate(&end_date, SystemToLocal64(x->notAfter));
+
+	// 同一の名前のオブジェクトがあれば削除
+	if (CheckSecObject(sec, name, SEC_X))
+	{
+		DeleteSecCert(sec, name);
+	}
+
+	// 作成
+	if ((ret = sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object)) != CKR_OK)
+	{
+		// 失敗
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		Debug("Error: 0x%02x\n", ret);
+		return false;
+	}
+
+	// キャッシュ消去
+	EraseEnumSecObjectCache(sec);
+
+	return true;
+}
+
+// 秘密鍵オブジェクトの削除
+bool DeleteSecKey(SECURE *sec, char *name)
+{
+	return DeleteSecObjectByName(sec, name, SEC_K);
+}
+
+// 証明書オブジェクトの削除
+bool DeleteSecCert(SECURE *sec, char *name)
+{
+	return DeleteSecObjectByName(sec, name, SEC_X);
+}
+
+// CK_DATE を 64 bit 時刻に変換
+UINT64 CkDateToUINT64(struct CK_DATE *ck_date)
+{
+	SYSTEMTIME st;
+	char year[32], month[32], day[32];
+	// 引数チェック
+	if (ck_date == NULL)
+	{
+		return 0;
+	}
+
+	Zero(year, sizeof(year));
+	Zero(month, sizeof(month));
+	Zero(day, sizeof(day));
+
+	Copy(year, ck_date->year, 4);
+	Copy(month, ck_date->month, 2);
+	Copy(day, ck_date->day, 2);
+
+	st.wYear = ToInt(year);
+	st.wMonth = ToInt(month);
+	st.wDay = ToInt(day);
+
+	return SystemToUINT64(&st);
+}
+
+// 64 bit 時刻を CK_DATE に変換
+void UINT64ToCkDate(void *p_ck_date, UINT64 time64)
+{
+	SYSTEMTIME st;
+	char year[32], month[32], day[32];
+	struct CK_DATE *ck_date = (CK_DATE *)p_ck_date;
+	// 引数チェック
+	if (ck_date == NULL)
+	{
+		return;
+	}
+
+	UINT64ToSystem(&st, time64);
+
+	Format(year, sizeof(year), "%04u", st.wYear);
+	Format(month, sizeof(month), "%04u", st.wMonth);
+	Format(day, sizeof(day), "%04u", st.wDay);
+
+	Zero(ck_date, sizeof(CK_DATE));
+
+	Copy(ck_date->year, year, 4);
+	Copy(ck_date->month, month, 2);
+	Copy(ck_date->day, day, 2);
+}
+
+// オブジェクトを名前で指定して削除
+bool DeleteSecObjectByName(SECURE *sec, char *name, UINT type)
+{
+	bool ret;
+	SEC_OBJ *obj;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (name == NULL)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+	}
+
+	// オブジェクト取得
+	obj = FindSecObject(sec, name, type);
+	if (obj == NULL)
+	{
+		// 失敗
+		return false;
+	}
+
+	// オブジェクト削除
+	ret = DeleteSecObject(sec, obj);
+
+	// メモリ解放
+	FreeSecObject(obj);
+
+	return ret;
+}
+
+// データの削除
+bool DeleteSecData(SECURE *sec, char *name)
+{
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (name == NULL)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+
+	return DeleteSecObjectByName(sec, name, SEC_DATA);
+}
+
+// セキュアオブジェクトの削除
+bool DeleteSecObject(SECURE *sec, SEC_OBJ *obj)
+{
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (obj == NULL)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+	}
+	if (sec->LoginFlag == false && obj->Private)
+	{
+		sec->Error = SEC_ERROR_NOT_LOGIN;
+		return false;
+	}
+
+	// オブジェクト消去
+	if (sec->Api->C_DestroyObject(sec->SessionId, obj->Object) != CKR_OK)
+	{
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		return false;
+	}
+
+	// キャッシュ消去
+	DeleteSecObjFromEnumCache(sec, obj->Name, obj->Type);
+
+	return true;
+}
+
+// キャッシュから指定した名前のオブジェクトを削除する
+void DeleteSecObjFromEnumCache(SECURE *sec, char *name, UINT type)
+{
+	UINT i;
+	// 引数チェック
+	if (sec == NULL || name == NULL || sec->EnumCache == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(sec->EnumCache);i++)
+	{
+		SEC_OBJ *obj = LIST_DATA(sec->EnumCache, i);
+
+		if (StrCmpi(obj->Name, name) == 0)
+		{
+			if (obj->Type == type)
+			{
+				Delete(sec->EnumCache, obj);
+				FreeSecObject(obj);
+				break;
+			}
+		}
+	}
+}
+
+// セキュアオブジェクトを名前で検索して読み込む
+int ReadSecData(SECURE *sec, char *name, void *data, UINT size)
+{
+	UINT ret = 0;
+	SEC_OBJ *obj;
+	// 引数チェック
+	if (sec == NULL || name == NULL || data == NULL)
+	{
+		return 0;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return 0;
+	}
+
+	// 読み込み
+	obj = FindSecObject(sec, name, SEC_DATA);
+	if (obj == NULL)
+	{
+		// 見つからない
+		return 0;
+	}
+
+	// 読み込む
+	ret = ReadSecDataFromObject(sec, obj, data, size);
+
+	FreeSecObject(obj);
+
+	return ret;
+}
+
+// キャッシュ消去
+void EraseEnumSecObjectCache(SECURE *sec)
+{
+	// 引数チェック
+	if (sec == NULL || sec->EnumCache == NULL)
+	{
+		return;
+	}
+
+	FreeEnumSecObject(sec->EnumCache);
+	sec->EnumCache = NULL;
+}
+
+// セキュアオブジェクトの存在をチェックする
+bool CheckSecObject(SECURE *sec, char *name, UINT type)
+{
+	SEC_OBJ *obj;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (name == NULL)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return 0;
+	}
+
+	obj = FindSecObject(sec, name, type);
+
+	if (obj == NULL)
+	{
+		return false;
+	}
+	else
+	{
+		FreeSecObject(obj);
+		return true;
+	}
+}
+
+// セキュアオブジェクト構造体のクローンの作成
+SEC_OBJ *CloneSecObject(SEC_OBJ *obj)
+{
+	SEC_OBJ *ret;
+	// 引数チェック
+	if (obj == NULL)
+	{
+		return NULL;
+	}
+
+	ret = ZeroMalloc(sizeof(SEC_OBJ));
+	ret->Name = CopyStr(obj->Name);
+	ret->Object = obj->Object;
+	ret->Private = obj->Private;
+	ret->Type = obj->Type;
+
+	return ret;
+}
+
+// セキュアオブジェクトを名前で検索して取得する
+SEC_OBJ *FindSecObject(SECURE *sec, char *name, UINT type)
+{
+	LIST *o;
+	UINT i;
+	SEC_OBJ *ret = NULL;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return NULL;
+	}
+	if (name == NULL)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return NULL;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return 0;
+	}
+
+	// 列挙
+	o = EnumSecObject(sec);
+	if (o == NULL)
+	{
+		return NULL;
+	}
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		SEC_OBJ *obj = LIST_DATA(o, i);
+
+		if (obj->Type == type || type == INFINITE)
+		{
+			if (StrCmpi(obj->Name, name) == 0)
+			{
+				ret = CloneSecObject(obj);
+				break;
+			}
+		}
+	}
+	FreeEnumSecObject(o);
+
+	if (ret == NULL)
+	{
+		sec->Error = SEC_ERROR_OBJ_NOT_FOUND;
+	}
+
+	return ret;
+}
+
+// セキュアオブジェクトの読み込み
+int ReadSecDataFromObject(SECURE *sec, SEC_OBJ *obj, void *data, UINT size)
+{
+	UCHAR buf[MAX_SEC_DATA_SIZE];
+	UINT i;
+	CK_ATTRIBUTE get[] =
+	{
+		{CKA_VALUE,	 buf,	sizeof(buf)},
+	};
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return 0;
+	}
+	if (obj == NULL || data == NULL || size == 0)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return 0;
+	}
+	if (obj->Type != SEC_DATA)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return 0;
+	}
+	if (sec->LoginFlag == false && obj->Private)
+	{
+		sec->Error = SEC_ERROR_NOT_LOGIN;
+		return 0;
+	}
+
+	// 取得
+	if (sec->Api->C_GetAttributeValue(
+		sec->SessionId, obj->Object, get, sizeof(get) / sizeof(get[0])) != CKR_OK)
+	{
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		return 0;
+	}
+
+	// 結果の返却
+	i = get[0].ulValueLen;
+	if (i > MAX_SEC_DATA_SIZE || i > size)
+	{
+		// データが大きすぎる
+		sec->Error = SEC_ERROR_DATA_TOO_BIG;
+		return 0;
+	}
+
+	// メモリコピー
+	Copy(data, buf, i);
+
+	return i;
+}
+
+// セキュアオブジェクトの列挙結果の解放
+void FreeEnumSecObject(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		SEC_OBJ *obj = LIST_DATA(o, i);
+
+		FreeSecObject(obj);
+	}
+
+	ReleaseList(o);
+}
+
+// セキュアオブジェクトの解放
+void FreeSecObject(SEC_OBJ *obj)
+{
+	// 引数チェック
+	if (obj == NULL)
+	{
+		return;
+	}
+
+	Free(obj->Name);
+	Free(obj);
+}
+
+// セキュアオブジェクト列挙結果のクローン
+LIST *CloneEnumSecObject(LIST *o)
+{
+	LIST *ret;
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	ret = NewListFast(NULL);
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		SEC_OBJ *obj = LIST_DATA(o, i);
+
+		Add(ret, CloneSecObject(obj));
+	}
+
+	return ret;
+}
+
+// セキュアオブジェクトの列挙
+LIST *EnumSecObject(SECURE *sec)
+{
+	CK_BBOOL b_true = true, b_false = false;
+	UINT objects[MAX_OBJ];
+	UINT i;
+	UINT ret;
+	LIST *o;
+	CK_ATTRIBUTE dummy[1];
+	CK_ATTRIBUTE a[] =
+	{
+		{CKA_TOKEN,		&b_true,		sizeof(b_true)},
+	};
+	UINT num_objects = MAX_OBJ;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return NULL;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return NULL;
+	}
+
+	Zero(dummy, sizeof(dummy));
+
+	// キャッシュがあればキャッシュを返す
+	if (sec->EnumCache != NULL)
+	{
+		return CloneEnumSecObject(sec->EnumCache);
+	}
+
+	// 列挙
+//	if (sec->Dev->Id != 2 && sec->Dev->Id != 14)
+//	{
+		// 通常のトークン
+		ret = sec->Api->C_FindObjectsInit(sec->SessionId, a, sizeof(a) / sizeof(a[0]));
+//	}
+//	else
+//	{
+		// ePass と SafeSign
+//		ret = sec->Api->C_FindObjectsInit(sec->SessionId, dummy, 0);
+//	}
+
+	if (ret != CKR_OK)
+	{
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		return NULL;
+	}
+	if (sec->Api->C_FindObjects(sec->SessionId, objects, sizeof(objects) / sizeof(objects[0]), &num_objects) != CKR_OK)
+	{
+		sec->Api->C_FindObjectsFinal(sec->SessionId);
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		return NULL;
+	}
+	sec->Api->C_FindObjectsFinal(sec->SessionId);
+
+	o = NewListFast(NULL);
+
+	for (i = 0;i < num_objects;i++)
+	{
+		char label[MAX_SIZE];
+		UINT obj_class = 0;
+		bool priv = false;
+		CK_ATTRIBUTE get[] =
+		{
+			{CKA_LABEL, label, sizeof(label) - 1},
+			{CKA_CLASS, &obj_class, sizeof(obj_class)},
+			{CKA_PRIVATE, &priv, sizeof(priv)},
+		};
+
+		Zero(label, sizeof(label));
+
+		if (sec->Api->C_GetAttributeValue(sec->SessionId, objects[i],
+			get, sizeof(get) / sizeof(get[0])) == CKR_OK)
+		{
+			UINT type = INFINITE;
+
+			switch (obj_class)
+			{
+			case CKO_DATA:
+				// データ
+				type = SEC_DATA;
+				break;
+
+			case CKO_CERTIFICATE:
+				// 証明書
+				type = SEC_X;
+				break;
+
+			case CKO_PUBLIC_KEY:
+				// 公開鍵
+				type = SEC_P;
+				break;
+
+			case CKO_PRIVATE_KEY:
+				// 秘密鍵
+				type = SEC_K;
+				break;
+			}
+
+			if (type != INFINITE)
+			{
+				SEC_OBJ *obj = ZeroMalloc(sizeof(SEC_OBJ));
+
+				obj->Type = type;
+				obj->Object = objects[i];
+				obj->Private = (priv == false) ? false : true;
+				EnSafeStr(label, '?');
+				TruncateCharFromStr(label, '?');
+				obj->Name = CopyStr(label);
+
+				Add(o, obj);
+			}
+		}
+	}
+
+	// キャッシュ作成
+	sec->EnumCache = CloneEnumSecObject(o);
+
+	return o;
+}
+
+// データを書き込む
+bool WriteSecData(SECURE *sec, bool private_obj, char *name, void *data, UINT size)
+{
+	UINT object_class = CKO_DATA;
+	CK_BBOOL b_true = true, b_false = false, b_private_obj = private_obj;
+	UINT object;
+	CK_ATTRIBUTE a[] =
+	{
+		{CKA_TOKEN,		&b_true,		sizeof(b_true)},
+		{CKA_CLASS,		&object_class,	sizeof(object_class)},
+		{CKA_PRIVATE,	&b_private_obj,	sizeof(b_private_obj)},
+		{CKA_LABEL,		name,			StrLen(name)},
+		{CKA_VALUE,		data,			size},
+	};
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+	}
+	if (private_obj && sec->LoginFlag == false)
+	{
+		sec->Error = SEC_ERROR_NOT_LOGIN;
+		return false;
+	}
+	if (name == NULL || data == NULL || size == 0)
+	{
+		sec->Error = SEC_ERROR_BAD_PARAMETER;
+		return false;
+	}
+	if (size > MAX_SEC_DATA_SIZE)
+	{
+		sec->Error = SEC_ERROR_DATA_TOO_BIG;
+		return false;
+	}
+
+	// 同名のオブジェクトがあれば削除
+	if (CheckSecObject(sec, name, SEC_DATA))
+	{
+		DeleteSecData(sec, name);
+	}
+
+	// オブジェクト作成
+	if (sec->Api->C_CreateObject(sec->SessionId, a, sizeof(a) / sizeof(a[0]), &object) != CKR_OK)
+	{
+		sec->Error = SEC_ERROR_HARDWARE_ERROR;
+		return false;
+	}
+
+	// キャッシュ消去
+	EraseEnumSecObjectCache(sec);
+
+	return true;
+}
+
+// キャッシュに新規作成したオブジェクトの情報を追加する
+void AddSecObjToEnumCache(SECURE *sec, char *name, UINT type, bool private_obj, UINT object)
+{
+	SEC_OBJ *obj;
+	// 引数チェック
+	if (sec == NULL || name == NULL || sec->EnumCache == NULL)
+	{
+		return;
+	}
+
+	obj = ZeroMalloc(sizeof(SEC_OBJ));
+	obj->Name = CopyStr(name);
+	obj->Object = object;
+	obj->Private = private_obj;
+	obj->Type = type;
+
+	Add(sec->EnumCache, obj);
+}
+
+// トークン情報を表示
+void PrintSecInfo(SECURE *sec)
+{
+	SEC_INFO *s;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return;
+	}
+
+	s = sec->Info;
+	if (s == NULL)
+	{
+		Print("No Token Info.\n");
+		return;
+	}
+
+	Print(
+		"               Label: %S\n"
+		"      ManufacturerId: %S\n"
+		"               Model: %S\n"
+		"        SerialNumber: %S\n"
+		"          MaxSession: %u\n"
+		"        MaxRWSession: %u\n"
+		"           MinPinLen: %u\n"
+		"           MaxPinLen: %u\n"
+		"   TotalPublicMemory: %u\n"
+		"    FreePublicMemory: %u\n"
+		"  TotalPrivateMemory: %u\n"
+		"   FreePrivateMemory: %u\n"
+		"     HardwareVersion: %s\n"
+		"     FirmwareVersion: %s\n",
+		s->Label, s->ManufacturerId, s->Model, s->SerialNumber,
+		s->MaxSession, s->MaxRWSession, s->MinPinLen, s->MaxPinLen,
+		s->TotalPublicMemory, s->FreePublicMemory, s->TotalPrivateMemory,
+		s->FreePrivateMemory, s->HardwareVersion, s->FirmwareVersion
+		);
+}
+
+// トークン情報を取得
+void GetSecInfo(SECURE *sec)
+{
+	CK_TOKEN_INFO token_info;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return;
+	}
+	if (sec->Info != NULL)
+	{
+		return;
+	}
+
+	// 取得
+	Zero(&token_info, sizeof(token_info));
+	if (sec->Api->C_GetTokenInfo(sec->SlotIdList[sec->SessionSlotNumber], &token_info) != CKR_OK)
+	{
+		// 失敗
+		return;
+	}
+
+	sec->Info = TokenInfoToSecInfo(&token_info);
+}
+
+// トークン情報を解放
+void FreeSecInfo(SECURE *sec)
+{
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return;
+	}
+	if (sec->Info == NULL)
+	{
+		return;
+	}
+
+	FreeSecInfoMemory(sec->Info);
+	sec->Info = NULL;
+}
+
+// トークン情報を SEC_INFO に変換
+SEC_INFO *TokenInfoToSecInfo(void *p_t)
+{
+	SEC_INFO *s;
+	char buf[MAX_SIZE];
+	CK_TOKEN_INFO *t = (CK_TOKEN_INFO *)p_t;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return NULL;
+	}
+
+	s = ZeroMalloc(sizeof(SEC_INFO));
+
+	// Label
+	Zero(buf, sizeof(buf));
+	Copy(buf, t->label, sizeof(t->label));
+	s->Label = ZeroMalloc(CalcUtf8ToUni(buf, 0));
+	Utf8ToUni(s->Label, 0, buf, 0);
+
+	// ManufacturerId
+	Zero(buf, sizeof(buf));
+	Copy(buf, t->manufacturerID, sizeof(t->manufacturerID));
+	s->ManufacturerId = ZeroMalloc(CalcUtf8ToUni(buf, 0));
+	Utf8ToUni(s->ManufacturerId, 0, buf, 0);
+
+	// Model
+	Zero(buf, sizeof(buf));
+	Copy(buf, t->model, sizeof(t->model));
+	s->Model = ZeroMalloc(CalcUtf8ToUni(buf, 0));
+	Utf8ToUni(s->Model, 0, buf, 0);
+
+	// SerialNumber
+	Zero(buf, sizeof(buf));
+	Copy(buf, t->serialNumber, sizeof(t->serialNumber));
+	s->SerialNumber = ZeroMalloc(CalcUtf8ToUni(buf, 0));
+	Utf8ToUni(s->SerialNumber, 0, buf, 0);
+
+	// 数値
+	s->MaxSession = t->ulMaxSessionCount;
+	s->MaxRWSession = t->ulMaxRwSessionCount;
+	s->MinPinLen = t->ulMinPinLen;
+	s->MaxPinLen = t->ulMaxPinLen;
+	s->TotalPublicMemory = t->ulTotalPublicMemory;
+	s->FreePublicMemory = t->ulFreePublicMemory;
+	s->TotalPrivateMemory = t->ulTotalPrivateMemory;
+	s->FreePrivateMemory = t->ulFreePrivateMemory;
+
+	// ハードウェアバージョン
+	Format(buf, sizeof(buf), "%u.%02u", t->hardwareVersion.major, t->hardwareVersion.minor);
+	s->HardwareVersion = CopyStr(buf);
+
+	// ファームウェアバージョン
+	Format(buf, sizeof(buf), "%u.%02u", t->firmwareVersion.major, t->firmwareVersion.minor);
+	s->FirmwareVersion = CopyStr(buf);
+
+	return s;
+}
+
+// SEC_INFO のメモリを解放
+void FreeSecInfoMemory(SEC_INFO *s)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	Free(s->Label);
+	Free(s->ManufacturerId);
+	Free(s->Model);
+	Free(s->SerialNumber);
+	Free(s->HardwareVersion);
+	Free(s->FirmwareVersion);
+	Free(s);
+}
+
+// ログアウトする
+void LogoutSec(SECURE *sec)
+{
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return;
+	}
+	if (sec->LoginFlag == false)
+	{
+		return;
+	}
+
+	// ログアウト
+	sec->Api->C_Logout(sec->SessionId);
+
+	// キャッシュ消去
+	EraseEnumSecObjectCache(sec);
+
+	sec->LoginFlag = false;
+}
+
+// ログインする
+bool LoginSec(SECURE *sec, char *pin)
+{
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (sec->SessionCreated == false)
+	{
+		sec->Error = SEC_ERROR_NO_SESSION;
+		return false;
+
+	}
+	if (sec->LoginFlag)
+	{
+		sec->Error = SEC_ERROR_ALREADY_LOGIN;
+		return false;
+	}
+	if (pin == NULL)
+	{
+		sec->Error = SEC_ERROR_NO_PIN_STR;
+		return false;
+	}
+
+	// ログイン
+	if (sec->Api->C_Login(sec->SessionId, CKU_USER, pin, StrLen(pin)) != CKR_OK)
+	{
+		// ログイン失敗
+		sec->Error = SEC_ERROR_BAD_PIN_CODE;
+		return false;
+	}
+
+	// キャッシュ消去
+	EraseEnumSecObjectCache(sec);
+
+	sec->LoginFlag = true;
+
+	return true;
+}
+
+// セッションを閉じる
+void CloseSecSession(SECURE *sec)
+{
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return;
+	}
+	if (sec->SessionCreated == false)
+	{
+		return;
+	}
+
+	// セッションを閉じる
+	sec->Api->C_CloseSession(sec->SessionId);
+
+	sec->SessionCreated = false;
+	sec->SessionId = 0;
+	sec->SessionSlotNumber = 0;
+
+	FreeSecInfo(sec);
+
+	// キャッシュ消去
+	EraseEnumSecObjectCache(sec);
+}
+
+// セッションを開く
+bool OpenSecSession(SECURE *sec, UINT slot_number)
+{
+	UINT err = 0;
+	UINT session;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+	if (sec->SessionCreated)
+	{
+		// すでに作成されている
+		sec->Error = SEC_ERROR_SESSION_EXISTS;
+		return false;
+	}
+	if (slot_number >= sec->NumSlot)
+	{
+		// スロット番号不正
+		sec->Error = SEC_ERROR_INVALID_SLOT_NUMBER;
+		return false;
+	}
+
+	// セッション作成
+	if ((err = sec->Api->C_OpenSession(sec->SlotIdList[slot_number],
+		CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK)
+	{
+		// 読み書きモードでのセッション初期化に失敗した
+		// 読み取り専用モードかな？
+		if ((err = sec->Api->C_OpenSession(sec->SlotIdList[slot_number],
+			CKF_SERIAL_SESSION, NULL, NULL, &session)) != CKR_OK)
+		{
+			// 作成失敗
+			sec->Error = SEC_ERROR_OPEN_SESSION;
+			return false;
+		}
+		else
+		{
+			sec->IsReadOnly = true;
+		}
+	}
+
+	sec->SessionCreated = true;
+	sec->SessionId = session;
+	sec->SessionSlotNumber = slot_number;
+
+	// トークン情報を取得
+	GetSecInfo(sec);
+
+	return true;
+}
+
+// セキュアデバイスを閉じる
+void CloseSec(SECURE *sec)
+{
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return;
+	}
+
+	// ログアウトする
+	LogoutSec(sec);
+
+	// セッションを閉じる
+	CloseSecSession(sec);
+
+	// トークン情報を解放
+	FreeSecInfo(sec);
+
+	// スロットリストメモリの解放
+	if (sec->SlotIdList != NULL)
+	{
+		Free(sec->SlotIdList);
+		sec->SlotIdList = NULL;
+	}
+
+	// モジュールのアンロード
+	FreeSecModule(sec);
+
+	// メモリ解放
+	DeleteLock(sec->lock);
+	Free(sec);
+}
+
+// セキュアデバイスを開く
+SECURE *OpenSec(UINT id)
+{
+	SECURE_DEVICE *dev = GetSecureDevice(id);
+	SECURE *sec;
+	UINT err;
+
+	if (dev == NULL)
+	{
+		return NULL;
+	}
+
+	sec = ZeroMalloc(sizeof(SECURE));
+
+	sec->lock = NewLock();
+	sec->Error = SEC_ERROR_NOERROR;
+	sec->Dev = dev;
+
+	// ePass かどうか取得する
+	if (SearchStrEx(dev->DeviceName, "epass", 0, false) != INFINITE)
+	{
+		sec->IsEPass1000 = true;
+	}
+
+	// モジュールのロード
+	if (LoadSecModule(sec) == false)
+	{
+		CloseSec(sec);
+		return NULL;
+	}
+
+	// スロット一覧の取得
+	sec->NumSlot = 0;
+	if ((err = sec->Api->C_GetSlotList(true, NULL, &sec->NumSlot)) != CKR_OK || sec->NumSlot == 0)
+	{
+		// 失敗
+		FreeSecModule(sec);
+		CloseSec(sec);
+		return NULL;
+	}
+
+	sec->SlotIdList = (UINT *)ZeroMalloc(sizeof(UINT *) * sec->NumSlot);
+
+	if (sec->Api->C_GetSlotList(TRUE, sec->SlotIdList, &sec->NumSlot) != CKR_OK)
+	{
+		// 失敗
+		Free(sec->SlotIdList);
+		sec->SlotIdList = NULL;
+		FreeSecModule(sec);
+		CloseSec(sec);
+		return NULL;
+	}
+
+	return sec;
+}
+
+// セキュアデバイスのモジュールをロードする
+bool LoadSecModule(SECURE *sec)
+{
+	bool ret = false;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return false;
+	}
+
+#ifdef	OS_WIN32
+	ret = Win32LoadSecModule(sec);
+#endif	// OS_WIN32
+
+	// 初期化
+	if (sec->Api->C_Initialize(NULL) != CKR_OK)
+	{
+		// 初期化失敗
+		FreeSecModule(sec);
+		return false;
+	}
+
+	sec->Initialized = true;
+
+	return ret;
+}
+
+// セキュアデバイスのモジュールをアンロードする
+void FreeSecModule(SECURE *sec)
+{
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return;
+	}
+
+	if (sec->Initialized)
+	{
+		// 初期化済みなので解放する
+		sec->Api->C_Finalize(NULL);
+		sec->Initialized = false;
+	}
+
+#ifdef	OS_WIN32
+	Win32FreeSecModule(sec);
+#endif	// OS_WIN32
+
+}
+
+
+// セキュアデバイスを取得する
+SECURE_DEVICE *GetSecureDevice(UINT id)
+{
+	UINT i;
+
+	if (id == 0)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < LIST_NUM(SecureDeviceList);i++)
+	{
+		SECURE_DEVICE *dev = LIST_DATA(SecureDeviceList, i);
+
+		if (dev->Id == id)
+		{
+			return dev;
+		}
+	}
+
+	return NULL;
+}
+
+// セキュアデバイスの ID を確認する
+bool CheckSecureDeviceId(UINT id)
+{
+	UINT i;
+
+	for (i = 0;i < LIST_NUM(SecureDeviceList);i++)
+	{
+		SECURE_DEVICE *dev = LIST_DATA(SecureDeviceList, i);
+
+		if (dev->Id == id)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// サポートされているデバイスリストを取得する
+LIST *GetSecureDeviceList()
+{
+	return GetSupportedDeviceList();
+}
+
+// サポートされているデバイスリストを取得する
+LIST *GetSupportedDeviceList()
+{
+	// 参照カウントの増加
+	AddRef(SecureDeviceList->ref);
+
+	return SecureDeviceList;
+}
+
+// 指定したデバイスがインストールされていて利用可能かどうか調べる
+bool IsDeviceSupported(SECURE_DEVICE *dev)
+{
+	bool b = false;
+#ifdef	OS_WIN32
+	b = Win32IsDeviceSupported(dev);
+#endif	// OS_WIN32
+	return b;
+}
+
+// セキュアデバイスリストの初期化
+void InitSecureDeviceList()
+{
+	UINT i, num_supported_list;
+	SecureDeviceList = NewList(NULL);
+
+	num_supported_list = sizeof(SupportedList) / sizeof(SECURE_DEVICE);
+	for (i = 0; i < num_supported_list;i++)
+	{
+		SECURE_DEVICE *dev = &SupportedList[i];
+
+		// サポートチェック
+		if (IsDeviceSupported(dev))
+		{
+			// サポートされているのでリストに追加
+			Add(SecureDeviceList, dev);
+		}
+	}
+}
+
+// テストメイン処理
+void TestSecMain(SECURE *sec)
+{
+	char *test_str = "SoftEther UT-VPN";
+	K *public_key, *private_key;
+	// 引数チェック
+	if (sec == NULL)
+	{
+		return;
+	}
+
+	Print("test_str: \"%s\"\n", test_str);
+
+	Print("Writing Data...\n");
+	if (WriteSecData(sec, true, "test_str", test_str, StrLen(test_str)) == false)
+	{
+		Print("WriteSecData() Failed.\n");
+	}
+	else
+	{
+		char data[MAX_SIZE];
+		Zero(data, sizeof(data));
+		Print("Reading Data...\n");
+		if (ReadSecData(sec, "test_str", data, sizeof(data)) == false)
+		{
+			Print("ReadSecData() Failed.\n");
+		}
+		else
+		{
+			Print("test_str: \"%s\"\n", data);
+		}
+		Print("Deleting Data...\n");
+		DeleteSecData(sec, "test_str");
+	}
+
+	Print("Generating Key...\n");
+	if (RsaGen(&private_key, &public_key, 1024) == false)
+	{
+		Print("RsaGen() Failed.\n");
+	}
+	else
+	{
+		X *cert;
+		NAME *name;
+		X_SERIAL *serial;
+		UINT num = 0x11220000;
+
+		Print("Creating Cert...\n");
+		serial = NewXSerial(&num, sizeof(UINT));
+		name = NewName(L"Test", L"Test", L"Test", L"JP", L"Test", L"Test");
+		cert = NewRootX(public_key, private_key, name, 365, NULL);
+		FreeXSerial(serial);
+		if (cert == NULL)
+		{
+			Print("NewRootX() Failed.\n");
+		}
+		else
+		{
+			Print("Writing Cert...\n");
+			DeleteSecData(sec, "test_cer");
+			if (WriteSecCert(sec, true, "test_cer", cert) == false)
+			{
+				Print("WriteSecCert() Failed.\n");
+			}
+			else
+			{
+				X *x;
+				Print("Reading Cert...\n");
+				x = ReadSecCert(sec, "test_cer");
+				if (x == NULL)
+				{
+					Print("ReadSecCert() Failed.\n");
+				}
+				else
+				{
+					Print("Checking two Certs... ");
+					if (CompareX(x, cert) == false)
+					{
+						Print("[FAILED]\n");
+					}
+					else
+					{
+						Print("Ok.\n");
+					}
+					FreeX(x);
+				}
+				if (cert != NULL)
+				{
+					X *x;
+					XToFile(cert, "cert_tmp.cer", true);
+					x = FileToX("cert_tmp.cer");
+					if (CompareX(x, cert) == false)
+					{
+						Print("[FAILED]\n");
+					}
+					else
+					{
+						Print("Ok.\n");
+						Print("Writing Private Key...\n");
+						DeleteSecKey(sec, "test_key");
+						if (WriteSecKey(sec, true, "test_key", private_key) == false)
+						{
+							Print("WriteSecKey() Failed.\n");
+						}
+						else
+						{
+							UCHAR sign_cpu[128];
+							UCHAR sign_sec[128];
+							K *pub = GetKFromX(cert);
+							Print("Ok.\n");
+							Print("Signing Data by CPU...\n");
+							if (RsaSign(sign_cpu, test_str, StrLen(test_str), private_key) == false)
+							{
+								Print("RsaSign() Failed.\n");
+							}
+							else
+							{
+								Print("Ok.\n");
+								Print("sign_cpu: ");
+								PrintBin(sign_cpu, sizeof(sign_cpu));
+								Print("Signing Data by %s..\n", sec->Dev->DeviceName);
+								if (SignSec(sec, "test_key", sign_sec, test_str, StrLen(test_str)) == false)
+								{
+									Print("SignSec() Failed.\n");
+								}
+								else
+								{
+									Print("Ok.\n");
+									Print("sign_sec: ");
+									PrintBin(sign_sec, sizeof(sign_sec));
+									Print("Compare...");
+									if (Cmp(sign_sec, sign_cpu, sizeof(sign_cpu)) == 0)
+									{
+										Print("Ok.\n");
+										Print("Verify...");
+										if (RsaVerify(test_str, StrLen(test_str),
+											sign_sec, pub) == false)
+										{
+											Print("[FAILED]\n");
+										}
+										else
+										{
+											Print("Ok.\n");
+										}
+									}
+									else
+									{
+										Print("[DIFFIRENT]\n");
+									}
+								}
+							}
+							Print("Deleting test_key...\n");
+//							DeleteSecKey(sec, "test_key");
+							FreeK(pub);
+						}
+					}
+					FreeX(x);
+				}
+			}
+			Print("Deleting Cert..\n");
+//			DeleteSecCert(sec, "test_cer");
+			FreeX(cert);
+		}
+		FreeName(name);
+		FreeK(private_key);
+		FreeK(public_key);
+	}
+}
+
+// セキュリティデバイスのテスト
+void TestSec()
+{
+	UINT i;
+	LIST *secure_device_list;
+	Print("Secure Device Test Program\n"
+		"Copyright (C) 2004-2010 SoftEther Corporation. All Rights Reserved.\n\n");
+
+	// セキュアデバイスリストの取得
+	secure_device_list = GetSecureDeviceList();
+	if (secure_device_list != NULL)
+	{
+		UINT use_device_id;
+		char tmp[MAX_SIZE];
+		Print("--- Secure Device List ---\n");
+		for (i = 0;i < LIST_NUM(secure_device_list);i++)
+		{
+			SECURE_DEVICE *dev = LIST_DATA(secure_device_list, i);
+			Print("%2u - %s\n", dev->Id, dev->DeviceName);
+		}
+		Print("\n");
+		Print("Device ID >");
+		GetLine(tmp, sizeof(tmp));
+		use_device_id = ToInt(tmp);
+		if (use_device_id == 0)
+		{
+			Print("Canceled.\n");
+		}
+		else
+		{
+			SECURE *sec = OpenSec(use_device_id);
+			Print("Opening Device...\n");
+			if (sec == NULL)
+			{
+				Print("OpenSec() Failed.\n");
+			}
+			else
+			{
+				Print("Opening Session...\n");
+				if (OpenSecSession(sec, 0) == false)
+				{
+					Print("OpenSecSession() Failed.\n");
+				}
+				else
+				{
+					while (true)
+					{
+						char pin[MAX_SIZE];
+						Print("PIN Code >");
+						GetLine(pin, sizeof(pin));
+						Trim(pin);
+						if (StrLen(pin) == 0)
+						{
+							Print("Canceled.\n");
+							break;
+						}
+						else
+						{
+							Print("Login...\n");
+							if (LoginSec(sec, pin))
+							{
+								TestSecMain(sec);
+								Print("Logout...\n");
+								LogoutSec(sec);
+								break;
+							}
+							else
+							{
+								Print("Login Failed. Please Try Again.\n");
+							}
+						}
+					}
+					Print("Closing Session...\n");
+					CloseSecSession(sec);
+				}
+				Print("Closing Device...\n");
+				CloseSec(sec);
+			}
+		}
+		ReleaseList(secure_device_list);
+	}
+	else
+	{
+		Print("GetSecureDeviceList() Error.\n");
+	}
+}
+
+// セキュアデバイスリストの解放
+void FreeSecureDeviceList()
+{
+	ReleaseList(SecureDeviceList);
+}
+
+// セキュリティトークンモジュールの初期化
+void InitSecure()
+{
+	// セキュアデバイスリストの初期化
+	InitSecureDeviceList();
+}
+
+// セキュリティトークンモジュールの解放
+void FreeSecure()
+{
+	// セキュアデバイスリストの解放
+	FreeSecureDeviceList();
+}
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Secure.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Secure.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Secure.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,294 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Secure.h
+// Secure.c のヘッダ
+
+#ifndef	SECURE_H
+#define	SECURE_H
+
+// 定数
+#define	MAX_SEC_DATA_SIZE		4096
+
+// PKCS#11 関係の型宣言
+#ifndef	SECURE_C
+typedef struct CK_FUNCTION_LIST *CK_FUNCTION_LIST_PTR;
+typedef struct SEC_DATA_WIN32	SEC_DATA_WIN32;
+typedef struct CK_TOKEN_INFO	CK_TOKEN_INFO;
+typedef struct CK_DATE			CK_DATE;
+#endif	// SECURE_C
+
+// セキュアデバイス
+struct SECURE_DEVICE
+{
+	UINT Id;								// デバイス ID
+	UINT Type;								// 種類
+	char *DeviceName;						// デバイス名
+	char *Manufacturer;						// 製造元
+	char *ModuleName;						// モジュール名
+};
+
+// セキュアデバイスの種類
+#define	SECURE_IC_CARD				0		// IC カード
+#define	SECURE_USB_TOKEN			1		// USB トークン
+
+// セキュアデバイス情報
+struct SEC_INFO
+{
+	wchar_t *Label;							// ラベル
+	wchar_t *ManufacturerId;					// 製造元 ID
+	wchar_t *Model;							// モデル
+	wchar_t *SerialNumber;						// シリアル番号
+	UINT MaxSession;						// 最大セッション数
+	UINT MaxRWSession;						// 最大 R/W セッション数
+	UINT MinPinLen;							// 最小 PIN 文字列長
+	UINT MaxPinLen;							// 最大 PIN 文字列長
+	UINT TotalPublicMemory;					// 合計メモリ容量 (Public)
+	UINT FreePublicMemory;					// 空きメモリ容量 (Private)
+	UINT TotalPrivateMemory;				// 合計メモリ容量 (Public)
+	UINT FreePrivateMemory;					// 空きメモリ容量 (Private)
+	char *HardwareVersion;					// ハードウェアバージョン
+	char *FirmwareVersion;					// ファームウェアバージョン
+};
+
+// セキュアデバイス構造体
+struct SECURE
+{
+	LOCK *lock;								// ロック
+	SECURE_DEVICE *Dev;						// デバイス情報
+	UINT Error;								// 最後に発生したエラー
+	struct CK_FUNCTION_LIST *Api;			// API
+	bool Initialized;						// 初期化フラグ
+	UINT NumSlot;							// スロット数
+	UINT *SlotIdList;						// スロット ID リスト
+	bool SessionCreated;					// セッション作成フラグ
+	UINT SessionId;							// セッション ID
+	UINT SessionSlotNumber;					// セッションのスロット ID
+	bool LoginFlag;							// ログイン済みフラグ
+	SEC_INFO *Info;							// トークン情報
+	LIST *EnumCache;						// 列挙キャッシュ
+
+	// ドライバごとに異なる挙動をするための属性値
+	bool IsEPass1000;						// ePass 1000
+	bool IsReadOnly;						// 読み取り専用モード
+
+#ifdef	OS_WIN32
+	struct SEC_DATA_WIN32 *Data;			// データ
+#endif	// OS_WIN32
+};
+
+// セキュアデバイスオブジェクト構造体
+struct SEC_OBJ
+{
+	UINT Type;								// オブジェクトの種類
+	UINT Object;							// オブジェクトハンドル
+	bool Private;							// プライベートフラグ
+	char *Name;								// 名前
+};
+
+#define	SEC_ERROR_NOERROR				0	// エラー無し
+#define	SEC_ERROR_INVALID_SLOT_NUMBER	1	// スロット番号が不正
+#define	SEC_ERROR_OPEN_SESSION			2	// セッション作成失敗
+#define	SEC_ERROR_SESSION_EXISTS		3	// すでにセッションが存在する
+#define	SEC_ERROR_NO_PIN_STR			4	// PIN 文字列が指定されていない
+#define	SEC_ERROR_ALREADY_LOGIN			5	// すでにログインしている
+#define	SEC_ERROR_BAD_PIN_CODE			6	// PIN コードが不正
+#define	SEC_ERROR_NO_SESSION			7	// セッションが存在しない
+#define	SEC_ERROR_DATA_TOO_BIG			8	// データが大きすぎる
+#define	SEC_ERROR_NOT_LOGIN				9	// ログインしていない
+#define	SEC_ERROR_BAD_PARAMETER			10	// パラメータ不正
+#define	SEC_ERROR_HARDWARE_ERROR		11	// ハードウェアエラー
+#define	SEC_ERROR_OBJ_NOT_FOUND			12	// オブジェクトが見つからない
+#define	SEC_ERROR_INVALID_CERT			13	// 証明書が不正
+
+
+#define	SEC_DATA						0	// データ
+#define	SEC_X							1	// 証明書
+#define	SEC_K							2	// 秘密鍵
+#define	SEC_P							3	// 公開鍵
+
+
+
+// 関数プロトタイプ
+void InitSecure();
+void FreeSecure();
+void InitSecureDeviceList();
+void FreeSecureDeviceList();
+bool IsDeviceSupported(SECURE_DEVICE *dev);
+LIST *GetSupportedDeviceList();
+LIST *GetSecureDeviceList();
+bool CheckSecureDeviceId(UINT id);
+SECURE_DEVICE *GetSecureDevice(UINT id);
+SECURE *OpenSec(UINT id);
+void CloseSec(SECURE *sec);
+bool OpenSecSession(SECURE *sec, UINT slot_number);
+void CloseSecSession(SECURE *sec);
+bool LoginSec(SECURE *sec, char *pin);
+void LogoutSec(SECURE *sec);
+void PrintSecInfo(SECURE *sec);
+LIST *EnumSecObject(SECURE *sec);
+void FreeSecObject(SEC_OBJ *obj);
+void FreeEnumSecObject(LIST *o);
+SEC_OBJ *FindSecObject(SECURE *sec, char *name, UINT type);
+bool CheckSecObject(SECURE *sec, char *name, UINT type);
+bool DeleteSecObjectByName(SECURE *sec, char *name, UINT type);
+SEC_OBJ *CloneSecObject(SEC_OBJ *obj);
+LIST *CloneEnumSecObject(LIST *o);
+void EraseEnumSecObjectCache(SECURE *sec);
+void DeleteSecObjFromEnumCache(SECURE *sec, char *name, UINT type);
+void AddSecObjToEnumCache(SECURE *sec, char *name, UINT type, bool private_obj, UINT object);
+bool WriteSecData(SECURE *sec, bool private_obj, char *name, void *data, UINT size);
+int ReadSecDataFromObject(SECURE *sec, SEC_OBJ *obj, void *data, UINT size);
+int ReadSecData(SECURE *sec, char *name, void *data, UINT size);
+bool DeleteSecObject(SECURE *sec, SEC_OBJ *obj);
+bool DeleteSecData(SECURE *sec, char *name);
+void UINT64ToCkDate(void *p_ck_date, UINT64 time64);
+bool WriteSecCert(SECURE *sec, bool private_obj, char *name, X *x);
+bool DeleteSecCert(SECURE *sec, char *name);
+X *ReadSecCertFromObject(SECURE *sec, SEC_OBJ *obj);
+X *ReadSecCert(SECURE *sec, char *name);
+bool WriteSecKey(SECURE *sec, bool private_obj, char *name, K *k);
+bool DeleteSecKey(SECURE *sec, char *name);
+bool SignSecByObject(SECURE *sec, SEC_OBJ *obj, void *dst, void *src, UINT size);
+bool SignSec(SECURE *sec, char *name, void *dst, void *src, UINT size);
+bool ChangePin(SECURE *sec, char *old_pin, char *new_pin);
+void TestSec();
+void TestSecMain(SECURE *sec);
+bool IsJPKI(bool id);
+
+bool LoadSecModule(SECURE *sec);
+void FreeSecModule(SECURE *sec);
+void GetSecInfo(SECURE *sec);
+void FreeSecInfo(SECURE *sec);
+SEC_INFO *TokenInfoToSecInfo(void *p_t);
+void FreeSecInfoMemory(SEC_INFO *s);
+
+#ifdef	OS_WIN32
+
+bool Win32IsDeviceSupported(SECURE_DEVICE *dev);
+bool Win32LoadSecModule(SECURE *sec);
+void Win32FreeSecModule(SECURE *sec);
+
+#endif	// OS_WIN32
+
+
+#ifdef	SECURE_C
+// 内部データ構造関連
+
+// サポートしているセキュアデバイスリスト
+static LIST *SecureDeviceList = NULL;
+
+// サポートしているハードウェアリスト
+// Q. なぜこのような静的なリストになっているのか? 動的に追加できないのか?
+// A. 今のところ、手抜きのためこのような実装になっている。
+SECURE_DEVICE SupportedList[] =
+{
+	{1,		SECURE_IC_CARD,		"Standard-9 IC Card",	"Dai Nippon Printing",	"DNPS9P11.DLL"},
+	{2,		SECURE_USB_TOKEN,	"ePass 1000",			"Feitian Technologies",	"EP1PK111.DLL"},
+	{3,		SECURE_IC_CARD,		"DNP Felica",			"Dai Nippon Printing",	"DNPFP11.DLL"},
+	{4,		SECURE_USB_TOKEN,	"eToken",				"Aladdin",				"ETPKCS11.DLL"},
+	{5,		SECURE_IC_CARD,		"Standard-9 IC Card",	"Fujitsu",				"F3EZSCL2.DLL"},
+	{6,		SECURE_IC_CARD,		"ASECard",				"Athena",				"ASEPKCS.DLL"},
+	{7,		SECURE_IC_CARD,		"Gemplus IC Card",		"Gemplus",				"PK2PRIV.DLL"},
+	{8,		SECURE_IC_CARD,		"1-Wire & iButton",		"DALLAS SEMICONDUCTOR",	"DSPKCS.DLL"},
+	{9,		SECURE_IC_CARD,		"JPKI IC Card",			"Japanese Government",	"JPKIPKCS11.DLL"},
+	{10,	SECURE_IC_CARD,		"LGWAN IC Card",		"Japanese Government",	"P11STD9.DLL"},
+	{11,	SECURE_IC_CARD,		"LGWAN IC Card",		"Japanese Government",	"P11STD9A.DLL"},
+	{12,	SECURE_USB_TOKEN,	"iKey 1000",			"Rainbow Technologies",	"K1PK112.DLL"},
+	{13,	SECURE_IC_CARD,		"JPKI IC Card #2",		"Japanese Government",	"libmusclepkcs11.dll"},
+	{14,	SECURE_USB_TOKEN,	"SafeSign",				"A.E.T.",				"aetpkss1.dll"},
+	{15,	SECURE_USB_TOKEN,	"LOCK STAR-PKI",		"Logicaltech Co.,LTD",	"LTPKCS11.dll"},
+	{16,	SECURE_USB_TOKEN,	"ePass 2000",			"Feitian Technologies",	"ep2pk11.dll"},
+	{17,	SECURE_IC_CARD,		"myuToken",				"iCanal Inc.",			"icardmodpk.dll"},
+};
+
+#ifdef	OS_WIN32
+
+// Win32 用内部データ
+typedef struct SEC_DATA_WIN32
+{
+	HINSTANCE hInst;
+} SEC_DATA_WIN32;
+
+#endif	// OS_WIN32
+
+#endif	// SECURE_C
+
+#endif	// SECURE_H
+
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Str.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Str.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Str.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,3068 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Str.c
+// 文字列処理ルーチン
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+// トークン関数の呼び出し用ロック処理
+LOCK *token_lock = NULL;
+static char *default_spliter = " ,\t\r\n";
+
+typedef struct BYTESTR
+{
+	UINT64 base_value;
+	char *string;
+} BYTESTR;
+
+static BYTESTR bytestr[] =
+{
+	{0, "PBytes"},
+	{0, "TBytes"},
+	{0, "GBytes"},
+	{0, "MBytes"},
+	{0, "KBytes"},
+	{0, "Bytes"},
+};
+
+// HEX 文字列を 64 bit 整数に変換
+UINT64 HexToInt64(char *str)
+{
+	UINT len, i;
+	UINT64 ret = 0;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+	{
+		str += 2;
+	}
+
+	len = StrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		char c = str[i];
+
+		if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
+		{
+			ret = ret * 16ULL + (UINT64)HexTo4Bit(c);
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	return ret;
+}
+
+// HEX 文字列を 32 bit 整数に変換
+UINT HexToInt(char *str)
+{
+	UINT len, i;
+	UINT ret = 0;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+	{
+		str += 2;
+	}
+
+	len = StrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		char c = str[i];
+
+		if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
+		{
+			ret = ret * 16 + (UINT)HexTo4Bit(c);
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	return ret;
+}
+
+// 64 bit 整数を HEX に変換
+void ToHex64(char *str, UINT64 value)
+{
+	char tmp[MAX_SIZE];
+	UINT wp = 0;
+	UINT len, i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	// 空文字に設定
+	StrCpy(tmp, 0, "");
+
+	// 末尾桁から追加する
+	while (true)
+	{
+		UINT a = (UINT)(value % (UINT64)16);
+		value = value / (UINT)16;
+		tmp[wp++] = FourBitToHex(a);
+		if (value == 0)
+		{
+			tmp[wp++] = 0;
+			break;
+		}
+	}
+
+	// 逆順にする
+	len = StrLen(tmp);
+	for (i = 0;i < len;i++)
+	{
+		str[len - i - 1] = tmp[i];
+	}
+	str[len] = 0;
+}
+
+// 32 bit 整数を HEX に変換
+void ToHex(char *str, UINT value)
+{
+	char tmp[MAX_SIZE];
+	UINT wp = 0;
+	UINT len, i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	// 空文字に設定
+	StrCpy(tmp, 0, "");
+
+	// 末尾桁から追加する
+	while (true)
+	{
+		UINT a = (UINT)(value % (UINT)16);
+		value = value / (UINT)16;
+		tmp[wp++] = FourBitToHex(a);
+		if (value == 0)
+		{
+			tmp[wp++] = 0;
+			break;
+		}
+	}
+
+	// 逆順にする
+	len = StrLen(tmp);
+	for (i = 0;i < len;i++)
+	{
+		str[len - i - 1] = tmp[i];
+	}
+	str[len] = 0;
+}
+
+// 4 bit 数値を 16 進文字列に変換
+char FourBitToHex(UINT value)
+{
+	value = value % 16;
+
+	if (value <= 9)
+	{
+		return '0' + value;
+	}
+	else
+	{
+		return 'a' + (value - 10);
+	}
+}
+
+// 16 進文字列を 4 bit 整数に変換
+UINT HexTo4Bit(char c)
+{
+	if ('0' <= c && c <= '9')
+	{
+		return c - '0';
+	}
+	else if ('a' <= c && c <= 'f')
+	{
+		return c - 'a' + 10;
+	}
+	else if ('A' <= c && c <= 'F')
+	{
+		return c - 'A' + 10;
+	}
+	else
+	{
+		return 0;
+	}
+}
+
+// 標準のトークン区切り文字を取得する
+char *DefaultTokenSplitChars()
+{
+	return " ,\t\r\n";
+}
+
+// 指定された文字が文字列に含まれるかどうかチェック
+bool IsCharInStr(char *str, char c)
+{
+	UINT i, len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	len = StrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		if (str[i] == c)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// 文字列からトークンを切り出す (区切り文字間の空間を無視しない)
+TOKEN_LIST *ParseTokenWithNullStr(char *str, char *split_chars)
+{
+	LIST *o;
+	UINT i, len;
+	BUF *b;
+	char zero = 0;
+	TOKEN_LIST *t;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NullToken();
+	}
+	if (split_chars == NULL)
+	{
+		split_chars = DefaultTokenSplitChars();
+	}
+
+	b = NewBuf();
+	o = NewListFast(NULL);
+
+	len = StrLen(str);
+
+	for (i = 0;i < (len + 1);i++)
+	{
+		char c = str[i];
+		bool flag = IsCharInStr(split_chars, c);
+
+		if (c == '\0')
+		{
+			flag = true;
+		}
+
+		if (flag == false)
+		{
+			WriteBuf(b, &c, sizeof(char));
+		}
+		else
+		{
+			WriteBuf(b, &zero, sizeof(char));
+
+			Insert(o, CopyStr((char *)b->Buf));
+			ClearBuf(b);
+		}
+	}
+
+	t = ZeroMalloc(sizeof(TOKEN_LIST));
+	t->NumTokens = LIST_NUM(o);
+	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		t->Token[i] = LIST_DATA(o, i);
+	}
+
+	ReleaseList(o);
+	FreeBuf(b);
+
+	return t;
+}
+
+// 文字列からトークンを切り出す (区切り文字間の空間を無視する)
+TOKEN_LIST *ParseTokenWithoutNullStr(char *str, char *split_chars)
+{
+	LIST *o;
+	UINT i, len;
+	bool last_flag;
+	BUF *b;
+	char zero = 0;
+	TOKEN_LIST *t;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NullToken();
+	}
+	if (split_chars == NULL)
+	{
+		split_chars = DefaultTokenSplitChars();
+	}
+
+	b = NewBuf();
+	o = NewListFast(NULL);
+
+	len = StrLen(str);
+	last_flag = false;
+
+	for (i = 0;i < (len + 1);i++)
+	{
+		char c = str[i];
+		bool flag = IsCharInStr(split_chars, c);
+
+		if (c == '\0')
+		{
+			flag = true;
+		}
+
+		if (flag == false)
+		{
+			WriteBuf(b, &c, sizeof(char));
+		}
+		else
+		{
+			if (last_flag == false)
+			{
+				WriteBuf(b, &zero, sizeof(char));
+
+				if ((StrLen((char *)b->Buf)) != 0)
+				{
+					Insert(o, CopyStr((char *)b->Buf));
+				}
+				ClearBuf(b);
+			}
+		}
+
+		last_flag = flag;
+	}
+
+	t = ZeroMalloc(sizeof(TOKEN_LIST));
+	t->NumTokens = LIST_NUM(o);
+	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		t->Token[i] = LIST_DATA(o, i);
+	}
+
+	ReleaseList(o);
+	FreeBuf(b);
+
+	return t;
+}
+
+// 文字列が含まれているかどうかチェック
+bool InStr(char *str, char *keyword)
+{
+	return InStrEx(str, keyword, false);
+}
+bool InStrEx(char *str, char *keyword, bool case_sensitive)
+{
+	// 引数チェック
+	if (IsEmptyStr(str) || IsEmptyStr(keyword))
+	{
+		return false;
+	}
+
+	if (SearchStrEx(str, keyword, 0, case_sensitive) == INFINITE)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// INI から値を取得
+UINT IniIntValue(LIST *o, char *key)
+{
+	INI_ENTRY *e;
+	// 引数チェック
+	if (o == NULL || key == NULL)
+	{
+		return 0;
+	}
+
+	e = GetIniEntry(o, key);
+	if (e == NULL)
+	{
+		return 0;
+	}
+
+	return ToInt(e->Value);
+}
+UINT64 IniInt64Value(LIST *o, char *key)
+{
+	INI_ENTRY *e;
+	// 引数チェック
+	if (o == NULL || key == NULL)
+	{
+		return 0;
+	}
+
+	e = GetIniEntry(o, key);
+	if (e == NULL)
+	{
+		return 0;
+	}
+
+	return ToInt64(e->Value);
+}
+char *IniStrValue(LIST *o, char *key)
+{
+	INI_ENTRY *e;
+	// 引数チェック
+	if (o == NULL || key == NULL)
+	{
+		return 0;
+	}
+
+	e = GetIniEntry(o, key);
+	if (e == NULL)
+	{
+		return "";
+	}
+
+	return e->Value;
+}
+wchar_t *IniUniStrValue(LIST *o, char *key)
+{
+	INI_ENTRY *e;
+	// 引数チェック
+	if (o == NULL || key == NULL)
+	{
+		return 0;
+	}
+
+	e = GetIniEntry(o, key);
+	if (e == NULL)
+	{
+		return L"";
+	}
+
+	return e->UnicodeValue;
+}
+
+// INI を解放する
+void FreeIni(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		INI_ENTRY *e = LIST_DATA(o, i);
+
+		Free(e->Key);
+		Free(e->Value);
+		Free(e->UnicodeValue);
+
+		Free(e);
+	}
+
+	ReleaseList(o);
+}
+
+// INI ファイルのエントリを取得する
+INI_ENTRY *GetIniEntry(LIST *o, char *key)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL || key == NULL)
+	{
+		return NULL;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		INI_ENTRY *e = LIST_DATA(o, i);
+
+		if (StrCmpi(e->Key, key) == 0)
+		{
+			return e;
+		}
+	}
+
+	return NULL;
+}
+
+// INI ファイルを読み込む
+LIST *ReadIni(BUF *b)
+{
+	LIST *o;
+	// 引数チェック
+	if (b == NULL)
+	{
+		return NULL;
+	}
+
+	o = NewListFast(NULL);
+
+	SeekBuf(b, 0, 0);
+
+	while (true)
+	{
+		char *line = CfgReadNextLine(b);
+
+		if (line == NULL)
+		{
+			break;
+		}
+
+		Trim(line);
+
+		if (IsEmptyStr(line) == false)
+		{
+			if (StartWith(line, "#") == false &&
+				StartWith(line, "//") == false &&
+				StartWith(line, ";") == false)
+			{
+				char *key, *value;
+				UINT size = StrLen(line) + 1;
+
+				key = ZeroMalloc(size);
+				value = ZeroMalloc(size);
+
+				if (GetKeyAndValue(line, key, size, value, size, NULL))
+				{
+					UINT uni_size;
+					INI_ENTRY *e = ZeroMalloc(sizeof(INI_ENTRY));
+					e->Key = CopyStr(key);
+					e->Value = CopyStr(value);
+
+					uni_size = CalcUtf8ToUni((BYTE *)value, StrLen(value));
+					e->UnicodeValue = ZeroMalloc(uni_size);
+					Utf8ToUni(e->UnicodeValue, uni_size, (BYTE *)value, StrLen(value));
+
+					Add(o, e);
+				}
+
+				Free(key);
+				Free(value);
+			}
+		}
+
+		Free(line);
+	}
+
+	return o;
+}
+
+// 指定された文字が区切り文字かどうかチェック
+bool IsSplitChar(char c, char *split_str)
+{
+	UINT i, len;
+	char c_upper = ToUpper(c);
+	if (split_str == NULL)
+	{
+		split_str = default_spliter;
+	}
+
+	len = StrLen(split_str);
+
+	for (i = 0;i < len;i++)
+	{
+		if (ToUpper(split_str[i]) == c_upper)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// 文字列からキーと値を取得する
+bool GetKeyAndValue(char *str, char *key, UINT key_size, char *value, UINT value_size, char *split_str)
+{
+	UINT mode = 0;
+	UINT wp1 = 0, wp2 = 0;
+	UINT i, len;
+	char *key_tmp, *value_tmp;
+	bool ret = false;
+	if (split_str == NULL)
+	{
+		split_str = default_spliter;
+	}
+
+	len = StrLen(str);
+
+	key_tmp = ZeroMalloc(len + 1);
+	value_tmp = ZeroMalloc(len + 1);
+
+	for (i = 0;i < len;i++)
+	{
+		char c = str[i];
+
+		switch (mode)
+		{
+		case 0:
+			if (IsSplitChar(c, split_str) == false)
+			{
+				mode = 1;
+				key_tmp[wp1] = c;
+				wp1++;
+			}
+			break;
+
+		case 1:
+			if (IsSplitChar(c, split_str) == false)
+			{
+				key_tmp[wp1] = c;
+				wp1++;
+			}
+			else
+			{
+				mode = 2;
+			}
+			break;
+
+		case 2:
+			if (IsSplitChar(c, split_str) == false)
+			{
+				mode = 3;
+				value_tmp[wp2] = c;
+				wp2++;
+			}
+			break;
+
+		case 3:
+			value_tmp[wp2] = c;
+			wp2++;
+			break;
+		}
+	}
+
+	if (mode != 0)
+	{
+		ret = true;
+		StrCpy(key, key_size, key_tmp);
+		StrCpy(value, value_size, value_tmp);
+	}
+
+	Free(key_tmp);
+	Free(value_tmp);
+
+	return ret;
+}
+
+// 指定した文字の列を生成する
+char *MakeCharArray(char c, UINT count)
+{
+	UINT i;
+	char *ret = Malloc(count + 1);
+
+	for (i = 0;i < count;i++)
+	{
+		ret[i] = c;
+	}
+
+	ret[count] = 0;
+
+	return ret;
+}
+void MakeCharArray2(char *str, char c, UINT count)
+{
+	UINT i;
+
+	for (i = 0;i < count;i++)
+	{
+		str[i] = c;
+	}
+
+	str[count] = 0;
+}
+
+// 指定した文字列の横幅を取得する
+UINT StrWidth(char *str)
+{
+	wchar_t *s;
+	UINT ret;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	s = CopyStrToUni(str);
+	ret = UniStrWidth(s);
+	Free(s);
+
+	return ret;
+}
+
+// 指定した文字列がすべて大文字かどうかチェックする
+bool IsAllUpperStr(char *str)
+{
+	UINT i, len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	len = StrLen(str);
+
+	for (i = 0;i < len;i++)
+	{
+		char c = str[i];
+
+		if ((c >= '0' && c <= '9') ||
+			(c >= 'A' && c <= 'Z'))
+		{
+		}
+		else
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+// 改行コードを正規化する
+char *NormalizeCrlf(char *str)
+{
+	char *ret;
+	UINT ret_size, i, len, wp;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	len = StrLen(str);
+	ret_size = sizeof(char) * (len + 32) * 2;
+	ret = Malloc(ret_size);
+
+	wp = 0;
+
+	for (i = 0;i < len;i++)
+	{
+		char c = str[i];
+
+		switch (c)
+		{
+		case '\r':
+			if (str[i + 1] == '\n')
+			{
+				i++;
+			}
+			ret[wp++] = '\r';
+			ret[wp++] = '\n';
+			break;
+
+		case '\n':
+			ret[wp++] = '\r';
+			ret[wp++] = '\n';
+			break;
+
+		default:
+			ret[wp++] = c;
+			break;
+		}
+	}
+
+	ret[wp++] = 0;
+
+	return ret;
+}
+
+// トークンリストを重複の無いものに変換する
+TOKEN_LIST *UniqueToken(TOKEN_LIST *t)
+{
+	UINT i, num, j, n;
+	TOKEN_LIST *ret;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return NULL;
+	}
+
+	num = 0;
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		bool exists = false;
+
+		for (j = 0;j < i;j++)
+		{
+			if (StrCmpi(t->Token[j], t->Token[i]) == 0)
+			{
+				exists = true;
+				break;
+			}
+		}
+
+		if (exists == false)
+		{
+			num++;
+		}
+	}
+
+	ret = ZeroMalloc(sizeof(TOKEN_LIST));
+	ret->Token = ZeroMalloc(sizeof(char *) * num);
+	ret->NumTokens = num;
+
+	n = 0;
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		bool exists = false;
+
+		for (j = 0;j < i;j++)
+		{
+			if (StrCmpi(t->Token[j], t->Token[i]) == 0)
+			{
+				exists = true;
+				break;
+			}
+		}
+
+		if (exists == false)
+		{
+			ret->Token[n++] = CopyStr(t->Token[i]);
+		}
+	}
+
+	return ret;
+}
+
+// バイト文字列に変換する (1,000 単位)
+void ToStrByte1000(char *str, UINT size, UINT64 v)
+{
+	UINT i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	// gcc での警告対策
+	bytestr[0].base_value = 1000000000UL;
+	bytestr[0].base_value *= 1000UL;
+	bytestr[0].base_value *= 1000UL;
+	bytestr[1].base_value = 1000000000UL;
+	bytestr[1].base_value *= 1000UL;
+	bytestr[2].base_value = 1000000000UL;
+	bytestr[3].base_value = 1000000UL;
+	bytestr[4].base_value = 1000UL;
+	bytestr[5].base_value = 0UL;
+
+	for (i = 0;i < sizeof(bytestr) / sizeof(bytestr[0]);i++)
+	{
+		BYTESTR *b = &bytestr[i];
+
+		if ((v * 11UL) / 10UL >= b->base_value)
+		{
+			if (b->base_value != 0)
+			{
+				double d = (double)v / (double)b->base_value;
+				Format(str, size, "%.2f %s", d, b->string);
+			}
+			else
+			{
+				Format(str, size, "%I64u %s", v, b->string);
+			}
+
+			break;
+		}
+	}
+}
+
+// バイト文字列に変換する
+void ToStrByte(char *str, UINT size, UINT64 v)
+{
+	UINT i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	// gcc での警告対策
+	bytestr[0].base_value = 1073741824UL;
+	bytestr[0].base_value *= 1024UL;
+	bytestr[0].base_value *= 1024UL;
+	bytestr[1].base_value = 1073741824UL;
+	bytestr[1].base_value *= 1024UL;
+	bytestr[2].base_value = 1073741824UL;
+	bytestr[3].base_value = 1048576UL;
+	bytestr[4].base_value = 1024UL;
+	bytestr[5].base_value = 0UL;
+
+	for (i = 0;i < sizeof(bytestr) / sizeof(bytestr[0]);i++)
+	{
+		BYTESTR *b = &bytestr[i];
+
+		if ((v * 11UL) / 10UL >= b->base_value)
+		{
+			if (b->base_value != 0)
+			{
+				double d = (double)v / (double)b->base_value;
+				Format(str, size, "%.2f %s", d, b->string);
+			}
+			else
+			{
+				Format(str, size, "%I64u %s", v, b->string);
+			}
+
+			break;
+		}
+	}
+}
+
+// 数字を文字列に変換して 3 桁ずつカンマで区切る
+void ToStr3(char *str, UINT size, UINT64 v)
+{
+	char tmp[128];
+	char tmp2[128];
+	UINT i, len, wp;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	ToStr64(tmp, v);
+
+	wp = 0;
+	len = StrLen(tmp);
+
+	for (i = len - 1;((int)i) >= 0;i--)
+	{
+		tmp2[wp++] = tmp[i];
+	}
+	tmp2[wp++] = 0;
+
+	wp = 0;
+
+	for (i = 0;i < len;i++)
+	{
+		if (i != 0 && (i % 3) == 0)
+		{
+			tmp[wp++] = ',';
+		}
+		tmp[wp++] = tmp2[i];
+	}
+	tmp[wp++] = 0;
+	wp = 0;
+	len = StrLen(tmp);
+
+	for (i = len - 1;((int)i) >= 0;i--)
+	{
+		tmp2[wp++] = tmp[i];
+	}
+	tmp2[wp++] = 0;
+
+	StrCpy(str, size, tmp2);
+}
+
+// MAC アドレスを文字列にする
+void MacToStr(char *str, UINT size, UCHAR *mac_address)
+{
+	// 引数チェック
+	if (str == NULL || mac_address == NULL)
+	{
+		return;
+	}
+
+	Format(str, size, "%02X-%02X-%02X-%02X-%02X-%02X",
+		mac_address[0],
+		mac_address[1],
+		mac_address[2],
+		mac_address[3],
+		mac_address[4],
+		mac_address[5]);
+}
+
+// 文字列が空かどうか調べる
+bool IsEmptyStr(char *str)
+{
+	char *s;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return true;
+	}
+
+	s = CopyStr(str);
+	Trim(s);
+
+	if (StrLen(s) == 0)
+	{
+		Free(s);
+		return true;
+	}
+	else
+	{
+		Free(s);
+		return false;
+	}
+}
+
+// トークンリストを文字列リストに変換する
+LIST *TokenListToList(TOKEN_LIST *t)
+{
+	UINT i;
+	LIST *o;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return NULL;
+	}
+
+	o = NewListFast(NULL);
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		Insert(o, CopyStr(t->Token[i]));
+	}
+
+	return o;
+}
+
+// 文字列リストをトークンリストに変換する
+TOKEN_LIST *ListToTokenList(LIST *o)
+{
+	UINT i;
+	TOKEN_LIST *t;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+
+	t = ZeroMalloc(sizeof(TOKEN_LIST));
+	t->NumTokens = LIST_NUM(o);
+	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		t->Token[i] = CopyStr(LIST_DATA(o, i));
+	}
+
+	return t;
+}
+
+// 文字列リストを解放する
+void FreeStrList(LIST *o)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		char *s = LIST_DATA(o, i);
+		Free(s);
+	}
+
+	ReleaseList(o);
+}
+
+// 文字列リストを文字列に変換する
+BUF *StrListToStr(LIST *o)
+{
+	BUF *b;
+	UINT i;
+	char c;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return NULL;
+	}
+	b = NewBuf();
+
+	for (i = 0;i < LIST_NUM(o);i++)
+	{
+		char *s = LIST_DATA(o, i);
+		WriteBuf(b, s, StrLen(s) + 1);
+	}
+
+	c = 0;
+	WriteBuf(b, &c, 1);
+
+	SeekBuf(b, 0, 0);
+
+	return b;
+}
+
+// 文字列 (NULL区切り) をリストに変換する
+LIST *StrToStrList(char *str, UINT size)
+{
+	LIST *o;
+	char *tmp;
+	UINT tmp_size;
+	UINT i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	o = NewListFast(NULL);
+
+	i = 0;
+	while (true)
+	{
+		if (i >= size)
+		{
+			break;
+		}
+		if (*str == 0)
+		{
+			break;
+		}
+
+		tmp_size = StrSize(str);
+		tmp = ZeroMalloc(tmp_size);
+		StrCpy(tmp, tmp_size, str);
+		Add(o, tmp);
+		str += StrLen(str) + 1;
+		i++;
+	}
+
+	return o;
+}
+
+// 指定された文字列が数字かどうかチェック
+bool IsNum(char *str)
+{
+	char c;
+	UINT i, len;
+	UINT n = 0;
+	char tmp[MAX_SIZE];
+	TOKEN_LIST *t;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	StrCpy(tmp, sizeof(tmp), str);
+	Trim(tmp);
+
+	if (StrLen(tmp) == 0)
+	{
+		return false;
+	}
+
+	t = ParseToken(tmp, " ");
+
+	if (t->NumTokens >= 1)
+	{
+		StrCpy(tmp, sizeof(tmp), t->Token[0]);
+	}
+
+	FreeToken(t);
+
+	len = StrLen(tmp);
+	for (i = 0;i < len;i++)
+	{
+		bool b = false;
+		c = tmp[i];
+		if (('0' <= c && c <= '9') || (c == '+') || (c == '-') || (c == ','))
+		{
+			b = true;
+		}
+
+		if (b == false)
+		{
+			return false;
+		}
+	}
+
+	for (i = 0;i < len;i++)
+	{
+		c = tmp[i];
+		if (c == '-')
+		{
+			n++;
+		}
+	}
+	if (n >= 2)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// 中身が無いトークンリスト
+TOKEN_LIST *NullToken()
+{
+	TOKEN_LIST *ret = ZeroMalloc(sizeof(TOKEN_LIST));
+	ret->Token = ZeroMalloc(0);
+
+	return ret;
+}
+
+// トークンリストのコピー
+TOKEN_LIST *CopyToken(TOKEN_LIST *src)
+{
+	TOKEN_LIST *ret;
+	UINT i;
+	// 引数チェック
+	if (src == NULL)
+	{
+		return NULL;
+	}
+
+	ret = ZeroMalloc(sizeof(TOKEN_LIST));
+	ret->NumTokens = src->NumTokens;
+	ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
+	for (i = 0;i < ret->NumTokens;i++)
+	{
+		ret->Token[i] = CopyStr(src->Token[i]);
+	}
+
+	return ret;
+}
+
+// コマンドラインをパースする
+TOKEN_LIST *ParseCmdLine(char *str)
+{
+	TOKEN_LIST *t;
+	LIST *o;
+	UINT i, len, wp, mode;
+	char c;
+	char *tmp;
+	bool ignore_space = false;
+	// 引数チェック
+	if (str == NULL)
+	{
+		// トークン無し
+		return NullToken();
+	}
+
+	o = NewListFast(NULL);
+	tmp = Malloc(StrSize(str) + 32);
+
+	wp = 0;
+	mode = 0;
+
+	len = StrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		c = str[i];
+
+		switch (mode)
+		{
+		case 0:
+			// 次のトークンを発見するモード
+			if (c == ' ' || c == '\t')
+			{
+				// 次の文字へ進める
+			}
+			else
+			{
+				// トークンの開始
+				if (c == '\"')
+				{
+					if (str[i + 1] == '\"')
+					{
+						// 2 重の " は 1 個の " 文字として見なす
+						tmp[wp++] = '\"';
+						i++;
+					}
+					else
+					{
+						// 1 個の " はスペース無視フラグを有効にする
+						ignore_space = true;
+					}
+				}
+				else
+				{
+					tmp[wp++] = c;
+				}
+
+				mode = 1;
+			}
+			break;
+
+		case 1:
+			if (ignore_space == false && (c == ' ' || c == '\t'))
+			{
+				// トークンの終了
+				tmp[wp++] = 0;
+				wp = 0;
+
+				Insert(o, CopyStr(tmp));
+				mode = 0;
+			}
+			else
+			{
+				if (c == '\"')
+				{
+					if (str[i + 1] == '\"')
+					{
+						// 2 重の " は 1 個の " 文字として見なす
+						tmp[wp++] = L'\"';
+						i++;
+					}
+					else
+					{
+						if (ignore_space == false)
+						{
+							// 1 個の " はスペース無視フラグを有効にする
+							ignore_space = true;
+						}
+						else
+						{
+							// スペース無視フラグを無効にする
+							ignore_space = false;
+						}
+					}
+				}
+				else
+				{
+					tmp[wp++] = c;
+				}
+			}
+			break;
+		}
+	}
+
+	if (wp != 0)
+	{
+		tmp[wp++] = 0;
+		Insert(o, CopyStr(tmp));
+	}
+
+	Free(tmp);
+
+	t = ZeroMalloc(sizeof(TOKEN_LIST));
+	t->NumTokens = LIST_NUM(o);
+	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		t->Token[i] = LIST_DATA(o, i);
+	}
+
+	ReleaseList(o);
+
+	return t;
+}
+
+// 64bit 整数を文字列に変換
+void ToStr64(char *str, UINT64 value)
+{
+	char tmp[MAX_SIZE];
+	UINT wp = 0;
+	UINT len, i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	// 空文字に設定
+	StrCpy(tmp, 0, "");
+
+	// 末尾桁から追加する
+	while (true)
+	{
+		UINT a = (UINT)(value % (UINT64)10);
+		value = value / (UINT64)10;
+		tmp[wp++] = (char)('0' + a);
+		if (value == 0)
+		{
+			tmp[wp++] = 0;
+			break;
+		}
+	}
+
+	// 逆順にする
+	len = StrLen(tmp);
+	for (i = 0;i < len;i++)
+	{
+		str[len - i - 1] = tmp[i];
+	}
+	str[len] = 0;
+}
+
+// 文字列を 64bit 整数に変換
+UINT64 ToInt64(char *str)
+{
+	UINT len, i;
+	UINT64 ret = 0;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	len = StrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		char c = str[i];
+		if (c != ',')
+		{
+			if ('0' <= c && c <= '9')
+			{
+				ret = ret * (UINT64)10 + (UINT64)(c - '0');
+			}
+			else
+			{
+				break;
+			}
+		}
+	}
+
+	return ret;
+}
+
+// str が key で終了するかどうかチェック
+bool EndWith(char *str, char *key)
+{
+	UINT str_len;
+	UINT key_len;
+	// 引数チェック
+	if (str == NULL || key == NULL)
+	{
+		return false;
+	}
+
+	// 比較
+	str_len = StrLen(str);
+	key_len = StrLen(key);
+	if (str_len < key_len)
+	{
+		return false;
+	}
+
+	if (StrCmpi(str + (str_len - key_len), key) == 0)
+	{
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+// str が key で始まるかどうかチェック
+bool StartWith(char *str, char *key)
+{
+	UINT str_len;
+	UINT key_len;
+	char *tmp;
+	bool ret;
+	// 引数チェック
+	if (str == NULL || key == NULL)
+	{
+		return false;
+	}
+
+	// 比較
+	str_len = StrLen(str);
+	key_len = StrLen(key);
+	if (str_len < key_len)
+	{
+		return false;
+	}
+	if (str_len == 0 || key_len == 0)
+	{
+		return false;
+	}
+	tmp = CopyStr(str);
+	tmp[key_len] = 0;
+
+	if (StrCmpi(tmp, key) == 0)
+	{
+		ret = true;
+	}
+	else
+	{
+		ret = false;
+	}
+
+	Free(tmp);
+
+	return ret;
+}
+
+// バイナリデータを表示
+void PrintBin(void *data, UINT size)
+{
+	char *tmp;
+	UINT i;
+	// 引数チェック
+	if (data == NULL)
+	{
+		return;
+	}
+
+	i = size * 3 + 1;
+	tmp = Malloc(i);
+	BinToStrEx(tmp, i, data, size);
+	Print("%s\n", tmp);
+	Free(tmp);
+}
+
+// 文字列を MAC アドレスに変換する
+bool StrToMac(UCHAR *mac_address, char *str)
+{
+	BUF *b;
+	// 引数チェック
+	if (mac_address == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	b = StrToBin(str);
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	if (b->Size != 6)
+	{
+		FreeBuf(b);
+		return false;
+	}
+
+	Copy(mac_address, b->Buf, 6);
+
+	FreeBuf(b);
+
+	return true;
+}
+
+// 16 進文字列をバイナリデータに変換する
+BUF *StrToBin(char *str)
+{
+	BUF *b;
+	UINT len, i;
+	char tmp[3];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	len = StrLen(str);
+	tmp[0] = 0;
+	b = NewBuf();
+	for (i = 0;i < len;i++)
+	{
+		char c = str[i];
+		c = ToUpper(c);
+		if (('0' <= c && c <= '9') || ('A' <= c && c <= 'F'))
+		{
+			if (tmp[0] == 0)
+			{
+				tmp[0] = c;
+				tmp[1] = 0;
+			}
+			else if (tmp[1] == 0)
+			{
+				UCHAR data;
+				char tmp2[64];
+				tmp[1] = c;
+				tmp[2] = 0;
+				StrCpy(tmp2, sizeof(tmp2), "0x");
+				StrCat(tmp2, sizeof(tmp2), tmp);
+				data = (UCHAR)strtoul(tmp2, NULL, 0);
+				WriteBuf(b, &data, 1);
+				Zero(tmp, sizeof(tmp));	
+			}
+		}
+		else if (c == ' ' || c == ',' || c == '-' || c == ':')
+		{
+			// 何もしない
+		}
+		else
+		{
+			break;
+		}
+	}
+
+	return b;
+}
+
+// バイナリデータを 16 進文字列に変換する (スペースも入れる)
+void BinToStrEx(char *str, UINT str_size, void *data, UINT data_size)
+{
+	char *tmp;
+	UCHAR *buf = (UCHAR *)data;
+	UINT size;
+	UINT i;
+	// 引数チェック
+	if (str == NULL || data == NULL)
+	{
+		return;
+	}
+
+	// サイズの計算
+	size = data_size * 3 + 1;
+	// メモリ確保
+	tmp = ZeroMalloc(size);
+	// 変換
+	for (i = 0;i < data_size;i++)
+	{
+		Format(&tmp[i * 3], 0, "%02X ", buf[i]);
+	}
+	Trim(tmp);
+	// コピー
+	StrCpy(str, str_size, tmp);
+	// メモリ解放
+	Free(tmp);
+}
+void BinToStrEx2(char *str, UINT str_size, void *data, UINT data_size, char padding_char)
+{
+	char *tmp;
+	UCHAR *buf = (UCHAR *)data;
+	UINT size;
+	UINT i;
+	// 引数チェック
+	if (str == NULL || data == NULL)
+	{
+		return;
+	}
+
+	// サイズの計算
+	size = data_size * 3 + 1;
+	// メモリ確保
+	tmp = ZeroMalloc(size);
+	// 変換
+	for (i = 0;i < data_size;i++)
+	{
+		Format(&tmp[i * 3], 0, "%02X%c", buf[i], padding_char);
+	}
+	if (StrLen(tmp) >= 1)
+	{
+		if (tmp[StrLen(tmp) - 1] == padding_char)
+		{
+			tmp[StrLen(tmp) - 1] = 0;
+		}
+	}
+	// コピー
+	StrCpy(str, str_size, tmp);
+	// メモリ解放
+	Free(tmp);
+}
+// バイナリデータを文字列に変換してコピーする
+char *CopyBinToStrEx(void *data, UINT data_size)
+{
+	char *ret;
+	UINT size;
+	// 引数チェック
+	if (data == NULL)
+	{
+		return NULL;
+	}
+
+	size = data_size * 3 + 1;
+	ret = ZeroMalloc(size);
+
+	BinToStrEx(ret, size, data, data_size);
+
+	return ret;
+}
+char *CopyBinToStr(void *data, UINT data_size)
+{
+	char *ret;
+	UINT size;
+	// 引数チェック
+	if (data == NULL)
+	{
+		return NULL;
+	}
+
+	size = data_size * 2 + 1;
+	ret = ZeroMalloc(size);
+
+	BinToStr(ret, size, data, data_size);
+
+	return ret;
+}
+
+// バイナリデータを 16 進文字列に変換する
+void BinToStr(char *str, UINT str_size, void *data, UINT data_size)
+{
+	char *tmp;
+	UCHAR *buf = (UCHAR *)data;
+	UINT size;
+	UINT i;
+	// 引数チェック
+	if (str == NULL || data == NULL)
+	{
+		if (str != NULL)
+		{
+			str[0] = 0;
+		}
+		return;
+	}
+
+	// サイズの計算
+	size = data_size * 2 + 1;
+	// メモリ確保
+	tmp = ZeroMalloc(size);
+	// 変換
+	for (i = 0;i < data_size;i++)
+	{
+		sprintf(&tmp[i * 2], "%02X", buf[i]);
+	}
+	// コピー
+	StrCpy(str, str_size, tmp);
+	// メモリ解放
+	Free(tmp);
+}
+void BinToStrW(wchar_t *str, UINT str_size, void *data, UINT data_size)
+{
+	char *tmp;
+	UINT tmp_size;
+	// 引数チェック
+	if (str == NULL || data == NULL)
+	{
+		if (str != NULL)
+		{
+			str[0] = 0;
+		}
+		return;
+	}
+
+	tmp_size = (data_size * 2 + 4) * sizeof(wchar_t);
+	tmp = ZeroMalloc(tmp_size);
+
+	BinToStr(tmp, tmp_size, data, data_size);
+
+	StrToUni(str, str_size, tmp);
+
+	Free(tmp);
+}
+
+// 160 ビット列を文字列にする
+void Bit160ToStr(char *str, UCHAR *data)
+{
+	// 引数チェック
+	if (str == NULL || data == NULL)
+	{
+		return;
+	}
+
+	Format(str, 0,
+		"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
+		data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], 
+		data[10], data[11], data[12], data[13], data[14], data[15], data[16], data[17], data[18], data[19]);
+}
+
+// 128 ビット列を文字列にする
+void Bit128ToStr(char *str, UCHAR *data)
+{
+	// 引数チェック
+	if (str == NULL || data == NULL)
+	{
+		return;
+	}
+
+	Format(str, 0,
+		"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
+		data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], 
+		data[10], data[11], data[12], data[13], data[14], data[15]);
+}
+
+// 文字列をコピーする
+char *CopyStr(char *str)
+{
+	UINT len;
+	char *dst;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NULL;
+	}
+
+	len = StrLen(str);
+	dst = Malloc(len + 1);
+	StrCpy(dst, len + 1, str);
+	return dst;
+}
+
+// 安全な文字列かどうかチェック
+bool IsSafeStr(char *str)
+{
+	UINT i, len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	len = StrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		if (IsSafeChar(str[i]) == false)
+		{
+			return false;
+		}
+	}
+	if (str[0] == ' ')
+	{
+		return false;
+	}
+	if (len != 0)
+	{
+		if (str[len - 1] == ' ')
+		{
+			return false;
+		}
+	}
+	return true;
+}
+
+// 安全な文字かどうかチェック
+bool IsSafeChar(char c)
+{
+	UINT i, len;
+	char *check_str =
+		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+		"abcdefghijklmnopqrstuvwxyz"
+		"0123456789"
+		" ()-_#%&.";
+
+	len = StrLen(check_str);
+	for (i = 0;i < len;i++)
+	{
+		if (c == check_str[i])
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
+// 文字列から指定した文字を削除する
+void TruncateCharFromStr(char *str, char replace)
+{
+	char *src,*dst;
+
+	if (str == NULL)
+	{
+		return;
+	}
+
+	src = dst = str;
+
+	while(*src != '\0')
+	{
+		if(*src != replace)
+		{
+			*dst = *src;
+			dst++;
+		}
+		src++;
+	}
+	*dst = *src;
+
+	//BUF *b = NewBuf();
+	//UINT i, len;
+	//char zero = 0;
+
+	//len = StrLen(str);
+	//for (i = 0;i < len;i++)
+	//{
+	//	char c = str[i];
+
+	//	if (c != replace)
+	//	{
+	//		WriteBuf(b, &c, 1);
+	//	}
+	//}
+
+	//if (b->Size == 0)
+	//{
+	//	char c = '_';
+	//	WriteBuf(b, &c, 1);
+	//}
+
+	//WriteBuf(b, &zero, 1);
+
+	//StrCpy(str, 0, b->Buf);
+
+	//FreeBuf(b);
+}
+
+// 安全な文字以外を置き換える
+void EnSafeStr(char *str, char replace)
+{
+	if (str == NULL)
+	{
+		return;
+	}
+
+	while(*str != '\0')
+	{
+		if(IsSafeChar(*str) == false)
+		{
+			*str = replace;
+		}
+		str++;
+	}
+}
+
+// 文字列ライブラリの動作チェック
+bool CheckStringLibrary()
+{
+	wchar_t *compare_str = L"TEST_TEST_123_123456789012345";
+	char *teststr = "TEST";
+	wchar_t *testunistr = L"TEST";
+	wchar_t tmp[64];
+	UINT i1 = 123;
+	UINT64 i2 = 123456789012345ULL;
+
+	UniFormat(tmp, sizeof(tmp), L"%S_%s_%u_%I64u", teststr, testunistr,
+		i1, i2);
+
+	if (UniStrCmpi(tmp, compare_str) != 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// 文字列ライブラリの初期化
+void InitStringLibrary()
+{
+	// トークン用ロックの作成
+	token_lock = NewLock();
+
+	// 国際ライブラリの初期化
+	InitInternational();
+
+	// 動作チェック
+	if (CheckStringLibrary() == false)
+	{
+#ifdef	OS_WIN32
+		Alert("String Library Init Failed.\r\nPlease check your locale settings.", NULL);
+#else	// OS_WIN32
+		Alert("String Library Init Failed.\r\nPlease check your locale settings and iconv() libraries.", NULL);
+#endif	// OS_WIN32
+		exit(0);
+	}
+}
+
+// 文字列ライブラリの解放
+void FreeStringLibrary()
+{
+	// 国際ライブラリの解放
+	FreeInternational();
+
+	// トークン用ロックの解放
+	DeleteLock(token_lock);
+	token_lock = NULL;
+}
+
+// 文字列の置換 (大文字小文字を区別しない)
+UINT ReplaceStri(char *dst, UINT size, char *string, char *old_keyword, char *new_keyword)
+{
+	return ReplaceStrEx(dst, size, string, old_keyword, new_keyword, false);
+}
+
+// 文字列の置換 (大文字小文字を区別する)
+UINT ReplaceStr(char *dst, UINT size, char *string, char *old_keyword, char *new_keyword)
+{
+	return ReplaceStrEx(dst, size, string, old_keyword, new_keyword, true);
+}
+
+// 文字列の置換
+UINT ReplaceStrEx(char *dst, UINT size, char *string, char *old_keyword, char *new_keyword, bool case_sensitive)
+{
+	UINT i, j, num;
+	UINT len_string, len_old, len_new;
+	UINT len_ret;
+	UINT wp;
+	char *ret;
+	// 引数チェック
+	if (string == NULL || old_keyword == NULL || new_keyword == NULL)
+	{
+		return 0;
+	}
+
+	// 文字列長の取得
+	len_string = StrLen(string);
+	len_old = StrLen(old_keyword);
+	len_new = StrLen(new_keyword);
+
+	// 最終文字列長の計算
+	len_ret = CalcReplaceStrEx(string, old_keyword, new_keyword, case_sensitive);
+	// メモリ確保
+	ret = Malloc(len_ret + 1);
+	ret[len_ret] = '\0';
+
+	// 検索と置換
+	i = 0;
+	j = 0;
+	num = 0;
+	wp = 0;
+	while (true)
+	{
+		i = SearchStrEx(string, old_keyword, i, case_sensitive);
+		if (i == INFINITE)
+		{
+			Copy(ret + wp, string + j, len_string - j);
+			wp += len_string - j;
+			break;
+		}
+		num++;
+		Copy(ret + wp, string + j, i - j);
+		wp += i - j;
+		Copy(ret + wp, new_keyword, len_new);
+		wp += len_new;
+		i += len_old;
+		j = i;
+	}
+
+	// 検索結果のコピー
+	StrCpy(dst, size, ret);
+
+	// メモリ解放
+	Free(ret);
+
+	return num;
+}
+
+// 文字列の置換後の文字列長を計算する
+UINT CalcReplaceStrEx(char *string, char *old_keyword, char *new_keyword, bool case_sensitive)
+{
+	UINT i, num;
+	UINT len_string, len_old, len_new;
+	// 引数チェック
+	if (string == NULL || old_keyword == NULL || new_keyword == NULL)
+	{
+		return 0;
+	}
+
+	// 文字列長の取得
+	len_string = StrLen(string);
+	len_old = StrLen(old_keyword);
+	len_new = StrLen(new_keyword);
+
+	if (len_old == len_new)
+	{
+		return len_string;
+	}
+
+	// 検索処理
+	num = 0;
+	i = 0;
+	while (true)
+	{
+		i = SearchStrEx(string, old_keyword, i, case_sensitive);
+		if (i == INFINITE)
+		{
+			break;
+		}
+		i += len_old;
+		num++;
+	}
+
+	// 計算
+	return len_string + len_new * num - len_old * num;
+}
+
+// 文字列の検索 (大文字 / 小文字を区別する)
+UINT SearchStr(char *string, char *keyword, UINT start)
+{
+	return SearchStrEx(string, keyword, start, true);
+}
+
+// 文字列の検索 (大文字 / 小文字を区別しない)
+UINT SearchStri(char *string, char *keyword, UINT start)
+{
+	return SearchStrEx(string, keyword, start, false);
+}
+
+// 文字列 string から文字列 keyword を検索して最初に見つかった文字の場所を返す
+// (1文字目に見つかったら 0, 見つからなかったら INFINITE)
+UINT SearchStrEx(char *string, char *keyword, UINT start, bool case_sensitive)
+{
+	UINT len_string, len_keyword;
+	UINT i;
+	char *cmp_string, *cmp_keyword;
+	bool found;
+	// 引数チェック
+	if (string == NULL || keyword == NULL)
+	{
+		return INFINITE;
+	}
+
+	// string の長さを取得
+	len_string = StrLen(string);
+	if (len_string <= start)
+	{
+		// start の値が不正
+		return INFINITE;
+	}
+
+	// keyword の長さを取得
+	len_keyword = StrLen(keyword);
+	if (len_keyword == 0)
+	{
+		// キーワードが無い
+		return INFINITE;
+	}
+
+	if ((len_string - start) < len_keyword)
+	{
+		// キーワードの長さのほうが長い
+		return INFINITE;
+	}
+
+	if (case_sensitive)
+	{
+		cmp_string = string;
+		cmp_keyword = keyword;
+	}
+	else
+	{
+		cmp_string = Malloc(len_string + 1);
+		StrCpy(cmp_string, len_string + 1, string);
+		cmp_keyword = Malloc(len_keyword + 1);
+		StrCpy(cmp_keyword, len_keyword + 1, keyword);
+		StrUpper(cmp_string);
+		StrUpper(cmp_keyword);
+	}
+
+	// 検索
+	found = false;
+	for (i = start;i < (len_string - len_keyword + 1);i++)
+	{
+		// 比較する
+		if (!strncmp(&cmp_string[i], cmp_keyword, len_keyword))
+		{
+			// 発見した
+			found = true;
+			break;
+		}
+	}
+
+	if (case_sensitive == false)
+	{
+		// メモリ解放
+		Free(cmp_keyword);
+		Free(cmp_string);
+	}
+
+	if (found == false)
+	{
+		return INFINITE;
+	}
+	return i;
+}
+
+// 指定した文字がトークンリスト内にあるかどうか調べる
+bool IsInToken(TOKEN_LIST *t, char *str)
+{
+	UINT i;
+	// 引数チェック
+	if (t == NULL || str == NULL)
+	{
+		return false;
+	}
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		if (StrCmpi(t->Token[i], str) == 0)
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+// トークンリストの解放
+void FreeToken(TOKEN_LIST *tokens)
+{
+	UINT i;
+	if (tokens == NULL)
+	{
+		return;
+	}
+	for (i = 0;i < tokens->NumTokens;i++)
+	{
+		if (tokens->Token[i] != 0)
+		{
+			Free(tokens->Token[i]);
+		}
+	}
+	Free(tokens->Token);
+	Free(tokens);
+}
+
+// トークンのパース
+TOKEN_LIST *ParseToken(char *src, char *separator)
+{
+	TOKEN_LIST *ret;
+	char *tmp;
+	char *str1, *str2;
+	UINT len;
+	UINT num;
+	if (src == NULL)
+	{
+		ret = ZeroMalloc(sizeof(TOKEN_LIST));
+		ret->Token = ZeroMalloc(0);
+		return ret;
+	}
+	if (separator == NULL)
+	{
+		separator = " ,\t\r\n";
+	}
+	len = StrLen(src);
+	str1 = Malloc(len + 1);
+	str2 = Malloc(len + 1);
+	StrCpy(str1, 0, src);
+	StrCpy(str2, 0, src);
+
+	Lock(token_lock);
+	{
+		tmp = strtok(str1, separator);
+		num = 0;
+		while (tmp != NULL)
+		{
+			num++;
+			tmp = strtok(NULL, separator);
+		}
+		ret = Malloc(sizeof(TOKEN_LIST));
+		ret->NumTokens = num;
+		ret->Token = (char **)Malloc(sizeof(char *) * num);
+		num = 0;
+		tmp = strtok(str2, separator);
+		while (tmp != NULL)
+		{
+			ret->Token[num] = (char *)Malloc(StrLen(tmp) + 1);
+			StrCpy(ret->Token[num], 0, tmp);
+			num++;
+			tmp = strtok(NULL, separator);
+		}
+	}
+	Unlock(token_lock);
+
+	Free(str1);
+	Free(str2);
+	return ret;
+}
+
+// 1 行を標準入力から取得
+bool GetLine(char *str, UINT size)
+{
+	bool ret;
+	wchar_t *unistr;
+	UINT unistr_size = (size + 1) * sizeof(wchar_t);
+
+	unistr = Malloc(unistr_size);
+
+	ret = UniGetLine(unistr, unistr_size);
+
+	UniToStr(str, size, unistr);
+
+	Free(unistr);
+
+	return ret;
+}
+
+// 末尾の \r \n を削除
+void TrimCrlf(char *str)
+{
+	UINT len;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+	len = StrLen(str);
+	if (len == 0)
+	{
+		return;
+	}
+
+	if (str[len - 1] == '\n')
+	{
+		if (len >= 2 && str[len - 2] == '\r')
+		{
+			str[len - 2] = 0;
+		}
+		str[len - 1] = 0;
+	}
+	else if (str[len - 1] == '\r')
+	{
+		str[len - 1] = 0;
+	}
+}
+
+// 文字列の左右の空白を削除
+void Trim(char *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	// 左側を trim
+	TrimLeft(str);
+
+	// 右側を trim
+	TrimRight(str);
+}
+
+// 文字列の右側の空白を削除
+void TrimRight(char *str)
+{
+	char *buf, *tmp;
+	UINT len, i, wp, wp2;
+	BOOL flag;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+	len = StrLen(str);
+	if (len == 0)
+	{
+		return;
+	}
+	if (str[len - 1] != ' ' && str[len - 1] != '\t')
+	{
+		return;
+	}
+
+	buf = Malloc(len + 1);
+	tmp = Malloc(len + 1);
+	flag = FALSE;
+	wp = 0;
+	wp2 = 0;
+	for (i = 0;i < len;i++)
+	{
+		if (str[i] != ' ' && str[i] != '\t')
+		{
+			Copy(buf + wp, tmp, wp2);
+			wp += wp2;
+			wp2 = 0;
+			buf[wp++] = str[i];
+		}
+		else
+		{
+			tmp[wp2++] = str[i];
+		}
+	}
+	buf[wp] = 0;
+	StrCpy(str, 0, buf);
+	Free(buf);
+	Free(tmp);
+}
+
+// 文字列の左側の空白を削除
+void TrimLeft(char *str)
+{
+	char *buf;
+	UINT len, i, wp;
+	BOOL flag;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+	len = StrLen(str);
+	if (len == 0)
+	{
+		return;
+	}
+	if (str[0] != ' ' && str[0] != '\t')
+	{
+		return;
+	}
+
+	buf = Malloc(len + 1);
+	flag = FALSE;
+	wp = 0;
+	for (i = 0;i < len;i++)
+	{
+		if (str[i] != ' ' && str[i] != '\t')
+		{
+			flag = TRUE;
+		}
+		if (flag)
+		{
+			buf[wp++] = str[i];
+		}
+	}
+	buf[wp] = 0;
+	StrCpy(str, 0, buf);
+	Free(buf);
+}
+
+// 整数を 16 進文字列に変換 (8桁固定)
+void ToStrx8(char *str, UINT i)
+{
+	sprintf(str, "0x%08x", i);
+}
+
+// 整数を 16 進文字列に変換
+void ToStrx(char *str, UINT i)
+{
+	sprintf(str, "0x%02x", i);
+}
+
+// 符号付整数を文字列に変換
+void ToStri(char *str, int i)
+{
+	sprintf(str, "%i", i);
+}
+
+// 整数を文字列に変換
+void ToStr(char *str, UINT i)
+{
+	sprintf(str, "%u", i);
+}
+
+// 文字列を符号付整数に変換
+int ToInti(char *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	return (int)ToInt(str);
+}
+
+// 文字列を bool に変換
+bool ToBool(char *str)
+{
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	StrCpy(tmp, sizeof(tmp), str);
+	Trim(tmp);
+
+	if (IsEmptyStr(tmp))
+	{
+		return false;
+	}
+
+	if (ToInt(tmp) != 0)
+	{
+		return true;
+	}
+
+	if (StartWith("true", tmp))
+	{
+		return true;
+	}
+
+	if (StartWith("yes", tmp))
+	{
+		return true;
+	}
+
+	if (StartWith(tmp, "true"))
+	{
+		return true;
+	}
+
+	if (StartWith(tmp, "yes"))
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// 文字列を整数に変換
+UINT ToInt(char *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	// 8 進数表記を無視する
+	while (true)
+	{
+		if (*str != '0')
+		{
+			break;
+		}
+		if ((*(str + 1) == 'x') || (*(str + 1) == 'X'))
+		{
+			break;
+		}
+		str++;
+	}
+
+	return (UINT)strtoul(str, NULL, 0);
+}
+
+// 64bit 整数のためのフォーマット文字列を置換する
+char *ReplaceFormatStringFor64(char *fmt)
+{
+	char *tmp;
+	char *ret;
+	UINT tmp_size;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return NULL;
+	}
+
+	tmp_size = StrSize(fmt) * 2;
+	tmp = ZeroMalloc(tmp_size);
+
+#ifdef	OS_WIN32
+	ReplaceStrEx(tmp, tmp_size, fmt, "%ll", "%I64", false);
+#else	// OS_WIN32
+	ReplaceStrEx(tmp, tmp_size, fmt, "%I64", "%ll", false);
+#endif	// OS_WIN32
+
+	ret = CopyStr(tmp);
+	Free(tmp);
+
+	return ret;
+}
+
+// 文字列を画面に表示する
+void PrintStr(char *str)
+{
+	wchar_t *unistr = NULL;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+#ifdef	OS_UNIX
+	fputs(str, stdout);
+#else	// OS_UNIX
+	unistr = CopyStrToUni(str);
+	UniPrintStr(unistr);
+	Free(unistr);
+#endif	// OS_UNIX
+}
+
+// 文字列を引数付きで表示する
+void PrintArgs(char *fmt, va_list args)
+{
+	wchar_t *ret;
+	wchar_t *fmt_wchar;
+	char *tmp;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return;
+	}
+
+	fmt_wchar = CopyStrToUni(fmt);
+	ret = InternalFormatArgs(fmt_wchar, args, true);
+
+	tmp = CopyUniToStr(ret);
+	PrintStr(tmp);
+	Free(tmp);
+
+	Free(ret);
+	Free(fmt_wchar);
+}
+
+// 文字列を表示する
+void Print(char *fmt, ...)
+{
+	va_list args;
+	if (fmt == NULL)
+	{
+		return;
+	}
+
+	va_start(args, fmt);
+	PrintArgs(fmt, args);
+	va_end(args);
+}
+
+// デバッグ文字列を引数付きで表示する
+void DebugArgs(char *fmt, va_list args)
+{
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return;
+	}
+	if (g_debug == false)
+	{
+		return;
+	}
+
+	PrintArgs(fmt, args);
+}
+
+// デバッグ文字列を表示する
+void Debug(char *fmt, ...)
+{
+	va_list args;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return;
+	}
+	if (g_debug == false)
+	{
+		return;
+	}
+
+	va_start(args, fmt);
+
+	DebugArgs(fmt, args);
+
+	va_end(args);
+}
+
+// 文字列をフォーマットして結果を返す
+char *CopyFormat(char *fmt, ...)
+{
+	char *buf;
+	char *ret;
+	UINT size;
+	va_list args;
+	// 引数チェック
+	if (fmt == NULL)
+	{
+		return NULL;
+	}
+
+	size = MAX(StrSize(fmt) * 10, MAX_SIZE * 10);
+	buf = Malloc(size);
+
+	va_start(args, fmt);
+	FormatArgs(buf, size, fmt, args);
+
+	ret = CopyStr(buf);
+	Free(buf);
+
+	va_end(args);
+	return ret;
+}
+
+// 文字列をフォーマットする
+void Format(char *buf, UINT size, char *fmt, ...)
+{
+	va_list args;
+	// 引数チェック
+	if (buf == NULL || fmt == NULL)
+	{
+		return;
+	}
+
+	va_start(args, fmt);
+	FormatArgs(buf, size, fmt, args);
+	va_end(args);
+}
+
+// 文字列をフォーマットする (引数リスト)
+void FormatArgs(char *buf, UINT size, char *fmt, va_list args)
+{
+	wchar_t *tag;
+	wchar_t *ret;
+	// 引数チェック
+	if (buf == NULL || fmt == NULL)
+	{
+		return;
+	}
+
+	tag = CopyStrToUni(fmt);
+	ret = InternalFormatArgs(tag, args, true);
+
+	UniToStr(buf, size, ret);
+	Free(ret);
+	Free(tag);
+}
+
+// 文字列を大文字・小文字を区別せずに比較する
+int StrCmpi(char *str1, char *str2)
+{
+	UINT i;
+	// 引数チェック
+	if (str1 == NULL && str2 == NULL)
+	{
+		return 0;
+	}
+	if (str1 == NULL)
+	{
+		return 1;
+	}
+	if (str2 == NULL)
+	{
+		return -1;
+	}
+
+	// 文字列比較
+	i = 0;
+	while (true)
+	{
+		char c1, c2;
+		c1 = ToUpper(str1[i]);
+		c2 = ToUpper(str2[i]);
+		if (c1 > c2)
+		{
+			return 1;
+		}
+		else if (c1 < c2)
+		{
+			return -1;
+		}
+		if (str1[i] == 0 || str2[i] == 0)
+		{
+			return 0;
+		}
+		i++;
+	}
+}
+
+// 文字列を比較する
+int StrCmp(char *str1, char *str2)
+{
+	// 引数チェック
+	if (str1 == NULL && str2 == NULL)
+	{
+		return 0;
+	}
+	if (str1 == NULL)
+	{
+		return 1;
+	}
+	if (str2 == NULL)
+	{
+		return -1;
+	}
+
+	return strcmp(str1, str2);
+}
+
+// 文字列を小文字にする
+void StrLower(char *str)
+{
+	UINT len, i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	len = StrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		str[i] = ToLower(str[i]);
+	}
+}
+
+// 文字列を大文字にする
+void StrUpper(char *str)
+{
+	UINT len, i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	len = StrLen(str);
+	for (i = 0;i < len;i++)
+	{
+		str[i] = ToUpper(str[i]);
+	}
+}
+
+// 文字を小文字にする
+char ToLower(char c)
+{
+	if ('A' <= c && c <= 'Z')
+	{
+		c += 'z' - 'Z';
+	}
+	return c;
+}
+
+// 文字を大文字にする
+char ToUpper(char c)
+{
+	if ('a' <= c && c <= 'z')
+	{
+		c += 'Z' - 'z';
+	}
+	return c;
+}
+
+// 文字列を結合
+UINT StrCat(char *dst, UINT size, char *src)
+{
+	UINT len1, len2, len_test;
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return 0;
+	}
+
+	// KS
+	KS_INC(KS_STRCAT_COUNT);
+
+	if (size == 0)
+	{
+		// 長さを無視
+		size = 0x7fffffff;
+	}
+
+	len1 = StrLen(dst);
+	len2 = StrLen(src);
+	len_test = len1 + len2 + 1;
+	if (len_test > size)
+	{
+		if (len2 <= (len_test - size))
+		{
+			return 0;
+		}
+		len2 -= len_test - size;
+	}
+	Copy(dst + len1, src, len2);
+	dst[len1 + len2] = 0;
+
+	return len1 + len2;
+}
+UINT StrCatLeft(char *dst, UINT size, char *src)
+{
+	char *s;
+	// 引数チェック
+	if (dst == NULL || src == NULL)
+	{
+		return 0;
+	}
+
+	s = CopyStr(dst);
+	StrCpy(dst, size, src);
+	StrCat(dst, size, s);
+
+	Free(s);
+
+	return StrLen(dst);
+}
+
+// 文字列をコピー
+UINT StrCpy(char *dst, UINT size, char *src)
+{
+	UINT len;
+	// 引数チェック
+	if (dst == src)
+	{
+		return StrLen(src);
+	}
+	if (dst == NULL || src == NULL)
+	{
+		if (src == NULL && dst != NULL)
+		{
+			if (size >= 1)
+			{
+				dst[0] = '\0';
+			}
+		}
+		return 0;
+	}
+	if (size == 1)
+	{
+		dst[0] = '\0';
+		return 0;
+	}
+	if (size == 0)
+	{
+		// 長さを無視
+		size = 0x7fffffff;
+	}
+
+	// 長さをチェック
+	len = StrLen(src);
+	if (len <= (size - 1))
+	{
+		Copy(dst, src, len + 1);
+	}
+	else
+	{
+		len = size - 1;
+		Copy(dst, src, len);
+		dst[len] = '\0';
+	}
+
+	// KS
+	KS_INC(KS_STRCPY_COUNT);
+
+	return len;
+}
+
+// 文字列バッファが指定されたサイズに収まっているかどうかを確認
+bool StrCheckSize(char *str, UINT size)
+{
+	// 引数チェック
+	if (str == NULL || size == 0)
+	{
+		return false;
+	}
+
+	return StrCheckLen(str, size - 1);
+}
+
+// 文字列が指定された長さ以内であることを確認
+bool StrCheckLen(char *str, UINT len)
+{
+	UINT count = 0;
+	UINT i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+
+	// KS
+	KS_INC(KS_STRCHECK_COUNT);
+
+	for (i = 0;;i++)
+	{
+		if (str[i] == '\0')
+		{
+			return true;
+		}
+		count++;
+		if (count > len)
+		{
+			return false;
+		}
+	}
+}
+
+// 文字列を格納するために必要なメモリサイズを取得
+UINT StrSize(char *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	return StrLen(str) + 1;
+}
+
+// 文字列の長さを取得
+UINT StrLen(char *str)
+{
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	// KS
+	KS_INC(KS_STRLEN_COUNT);
+
+	return (UINT)strlen(str);
+}
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Str.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Str.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Str.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,209 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Str.h
+// Str.c のヘッダ
+
+#ifndef	STR_H
+#define	STR_H
+
+// 文字列トークン
+struct TOKEN_LIST
+{
+	UINT NumTokens;
+	char **Token;
+};
+
+// INI_ENTRY
+struct INI_ENTRY
+{
+	char *Key;
+	char *Value;
+	wchar_t *UnicodeValue;
+};
+
+// 関数プロトタイプ
+UINT StrLen(char *str);
+UINT StrSize(char *str);
+bool StrCheckLen(char *str, UINT len);
+bool StrCheckSize(char *str, UINT size);
+UINT StrCpy(char *dst, UINT size, char *src);
+UINT StrCat(char *dst, UINT size, char *src);
+UINT StrCatLeft(char *dst, UINT size, char *src);
+char ToLower(char c);
+char ToUpper(char c);
+void StrUpper(char *str);
+void StrLower(char *str);
+int StrCmp(char *str1, char *str2);
+int StrCmpi(char *str1, char *str2);
+void FormatArgs(char *buf, UINT size, char *fmt, va_list args);
+void Format(char *buf, UINT size, char *fmt, ...);
+char *CopyFormat(char *fmt, ...);
+void Print(char *fmt, ...);
+void PrintArgs(char *fmt, va_list args);
+void PrintStr(char *str);
+void Debug(char *fmt, ...);
+void DebugArgs(char *fmt, va_list args);
+UINT ToInt(char *str);
+bool ToBool(char *str);
+int ToInti(char *str);
+void ToStr(char *str, UINT i);
+void ToStri(char *str, int i);
+void ToStrx(char *str, UINT i);
+void ToStrx8(char *str, UINT i);
+void TrimCrlf(char *str);
+void Trim(char *str);
+void TrimRight(char *str);
+void TrimLeft(char *str);
+bool GetLine(char *str, UINT size);
+void FreeToken(TOKEN_LIST *tokens);
+bool IsInToken(TOKEN_LIST *t, char *str);
+TOKEN_LIST *ParseToken(char *src, char *separator);
+void InitStringLibrary();
+void FreeStringLibrary();
+bool CheckStringLibrary();
+UINT SearchStrEx(char *string, char *keyword, UINT start, bool case_sensitive);
+UINT SearchStri(char *string, char *keyword, UINT start);
+UINT SearchStr(char *string, char *keyword, UINT start);
+UINT CalcReplaceStrEx(char *string, char *old_keyword, char *new_keyword, bool case_sensitive);
+UINT ReplaceStrEx(char *dst, UINT size, char *string, char *old_keyword, char *new_keyword, bool case_sensitive);
+UINT ReplaceStr(char *dst, UINT size, char *string, char *old_keyword, char *new_keyword);
+UINT ReplaceStri(char *dst, UINT size, char *string, char *old_keyword, char *new_keyword);
+bool IsSafeChar(char c);
+bool IsSafeStr(char *str);
+void EnSafeStr(char *str, char replace);
+void TruncateCharFromStr(char *str, char replace);
+char *CopyStr(char *str);
+void BinToStr(char *str, UINT str_size, void *data, UINT data_size);
+void BinToStrW(wchar_t *str, UINT str_size, void *data, UINT data_size);
+void PrintBin(void *data, UINT size);
+bool StartWith(char *str, char *key);
+bool EndWith(char *str, char *key);
+UINT64 ToInt64(char *str);
+void ToStr64(char *str, UINT64 value);
+char *ReplaceFormatStringFor64(char *fmt);
+TOKEN_LIST *ParseCmdLine(char *str);
+TOKEN_LIST *CopyToken(TOKEN_LIST *src);
+TOKEN_LIST *NullToken();
+bool IsNum(char *str);
+LIST *StrToStrList(char *str, UINT size);
+BUF *StrListToStr(LIST *o);
+void FreeStrList(LIST *o);
+TOKEN_LIST *ListToTokenList(LIST *o);
+LIST *TokenListToList(TOKEN_LIST *t);
+bool IsEmptyStr(char *str);
+void BinToStrEx(char *str, UINT str_size, void *data, UINT data_size);
+void BinToStrEx2(char *str, UINT str_size, void *data, UINT data_size, char padding_char);
+char *CopyBinToStrEx(void *data, UINT data_size);
+char *CopyBinToStr(void *data, UINT data_size);
+BUF *StrToBin(char *str);
+void MacToStr(char *str, UINT size, UCHAR *mac_address);
+void ToStr3(char *str, UINT size, UINT64 v);
+void ToStrByte(char *str, UINT size, UINT64 v);
+void ToStrByte1000(char *str, UINT size, UINT64 v);
+TOKEN_LIST *UniqueToken(TOKEN_LIST *t);
+char *NormalizeCrlf(char *str);
+bool IsAllUpperStr(char *str);
+UINT StrWidth(char *str);
+char *MakeCharArray(char c, UINT count);
+void MakeCharArray2(char *str, char c, UINT count);
+bool StrToMac(UCHAR *mac_address, char *str);
+bool IsSplitChar(char c, char *split_str);
+bool GetKeyAndValue(char *str, char *key, UINT key_size, char *value, UINT value_size, char *split_str);
+LIST *ReadIni(BUF *b);
+INI_ENTRY *GetIniEntry(LIST *o, char *key);
+void FreeIni(LIST *o);
+UINT IniIntValue(LIST *o, char *key);
+UINT64 IniInt64Value(LIST *o, char *key);
+char *IniStrValue(LIST *o, char *key);
+wchar_t *IniUniStrValue(LIST *o, char *key);
+bool InStr(char *str, char *keyword);
+bool InStrEx(char *str, char *keyword, bool case_sensitive);
+TOKEN_LIST *ParseTokenWithoutNullStr(char *str, char *split_chars);
+TOKEN_LIST *ParseTokenWithNullStr(char *str, char *split_chars);
+char *DefaultTokenSplitChars();
+bool IsCharInStr(char *str, char c);
+UINT HexTo4Bit(char c);
+char FourBitToHex(UINT value);
+void ToHex(char *str, UINT value);
+void ToHex64(char *str, UINT64 value);
+UINT HexToInt(char *str);
+UINT64 HexToInt64(char *str);
+
+
+#endif	// STR_H
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Table.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Table.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Table.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,865 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Table.c
+// 文字列テーブル読み込み & 管理ルーチン
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+// TABLE のリスト
+static LIST *TableList = NULL;
+static wchar_t old_table_name[MAX_SIZE] = {0};		// 古いテーブル名
+
+// エラー文字列を Unicode で取得する
+wchar_t *GetUniErrorStr(UINT err)
+{
+	wchar_t *ret;
+	char name[MAX_SIZE];
+	Format(name, sizeof(name), "ERR_%u", err);
+
+	ret = GetTableUniStr(name);
+	if (UniStrLen(ret) != 0)
+	{
+		return ret;
+	}
+	else
+	{
+		return _UU("ERR_UNKNOWN");
+	}
+}
+
+// エラー文字列を取得する
+char *GetErrorStr(UINT err)
+{
+	char *ret;
+	char name[MAX_SIZE];
+	Format(name, sizeof(name), "ERR_%u", err);
+
+	ret = GetTableStr(name);
+	if (StrLen(ret) != 0)
+	{
+		return ret;
+	}
+	else
+	{
+		return _SS("ERR_UNKNOWN");
+	}
+}
+
+// テーブルから整数値をロードする
+UINT GetTableInt(char *name)
+{
+	char *str;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return 0;
+	}
+
+	str = GetTableStr(name);
+	return ToInt(str);
+}
+
+// テーブルから Unicode 文字列をロードする
+wchar_t *GetTableUniStr(char *name)
+{
+	TABLE *t;
+	// 引数チェック
+	if (name == NULL)
+	{
+//		Debug("%s: ************\n", name);
+		return L"";
+	}
+
+	// 検索
+	t = FindTable(name);
+	if (t == NULL)
+	{
+//		Debug("%s: UNICODE STRING NOT FOUND\n", name);
+		return L"";
+	}
+
+	return t->unistr;
+}
+
+// テーブルから文字列をロードする
+char *GetTableStr(char *name)
+{
+	TABLE *t;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return "";
+	}
+
+#ifdef	OS_WIN32
+	if (StrCmpi(name, "DEFAULT_FONT") == 0)
+	{
+		if (_II("LANG") == 2)
+		{
+			UINT os_type = GetOsType();
+			if (OS_IS_WINDOWS_9X(os_type) ||
+				GET_KETA(os_type, 100) <= 4)
+			{
+				// Windows 9x, Windows NT 4.0, Windows 2000, Windows XP, Windows Server 2003 の場合は SimSun フォントを利用する
+				return "SimSun";
+			}
+		}
+	}
+#endif	// OS_WIN32
+
+	// 検索
+	t = FindTable(name);
+	if (t == NULL)
+	{
+//		Debug("%s: ANSI STRING NOT FOUND\n", name);
+		return "";
+	}
+
+	return t->str;
+}
+
+// 指定した名前で始まる文字列名を取得する
+TOKEN_LIST *GetTableNameStartWith(char *str)
+{
+	UINT i;
+	UINT len;
+	LIST *o;
+	TOKEN_LIST *t;
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (str == NULL)
+	{
+		return NullToken();
+	}
+
+	StrCpy(tmp, sizeof(tmp), str);
+	StrUpper(tmp);
+
+	len = StrLen(tmp);
+
+	o = NewListFast(NULL);
+
+	for (i = 0;i < LIST_NUM(TableList);i++)
+	{
+		TABLE *t = LIST_DATA(TableList, i);
+		UINT len2 = StrLen(t->name);
+
+		if (len2 >= len)
+		{
+			if (Cmp(t->name, tmp, len) == 0)
+			{
+				Insert(o, CopyStr(t->name));
+			}
+		}
+	}
+
+	t = ZeroMalloc(sizeof(TOKEN_LIST));
+	t->NumTokens = LIST_NUM(o);
+	t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
+
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		t->Token[i] = LIST_DATA(o, i);
+	}
+
+	ReleaseList(o);
+
+	return t;
+}
+
+// テーブルを検索する
+TABLE *FindTable(char *name)
+{
+	TABLE *t, tt;
+	// 引数チェック
+	if (name == NULL || TableList == NULL)
+	{
+		return NULL;
+	}
+
+	tt.name = CopyStr(name);
+	t = Search(TableList, &tt);
+	Free(tt.name);
+
+	return t;
+}
+
+// テーブル名を比較する関数
+int CmpTableName(void *p1, void *p2)
+{
+	TABLE *t1, *t2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	t1 = *(TABLE **)p1;
+	t2 = *(TABLE **)p2;
+	if (t1 == NULL || t2 == NULL)
+	{
+		return 0;
+	}
+
+	return StrCmpi(t1->name, t2->name);
+}
+
+// 1 行を解釈する
+TABLE *ParseTableLine(char *line, char *prefix, UINT prefix_size)
+{
+	UINT i, len;
+	UINT len_name;
+	UINT string_start;
+	char *name;
+	char *name2;
+	UINT name2_size;
+	wchar_t *unistr;
+	char *str;
+	UINT unistr_size, str_size;
+	TABLE *t;
+	// 引数チェック
+	if (line == NULL || prefix == NULL)
+	{
+		return NULL;
+	}
+	TrimLeft(line);
+
+	// 行無し
+	len = StrLen(line);
+	if (len == 0)
+	{
+		return NULL;
+	}
+
+	// コメント
+	if (line[0] == '#' || (line[0] == '/' && line[1] == '/'))
+	{
+		return NULL;
+	}
+
+	// 名前の終了位置まで検索
+	len_name = 0;
+	for (i = 0;;i++)
+	{
+		if (line[i] == 0)
+		{
+			// トークンが 1 つしか無い
+			return NULL;
+		}
+		if (line[i] == ' ' || line[i] == '\t')
+		{
+			break;
+		}
+		len_name++;
+	}
+
+	name = Malloc(len_name + 1);
+	StrCpy(name, len_name + 1, line);
+
+	string_start = len_name;
+	for (i = len_name;i < len;i++)
+	{
+		if (line[i] != ' ' && line[i] != '\t')
+		{
+			break;
+		}
+		string_start++;
+	}
+	if (i == len)
+	{
+		Free(name);
+		return NULL;
+	}
+
+	// アンエスケープ
+	UnescapeStr(&line[string_start]);
+
+	// Unicode に変換する
+	unistr_size = CalcUtf8ToUni(&line[string_start], StrLen(&line[string_start]));
+	if (unistr_size == 0)
+	{
+		Free(name);
+		return NULL;
+	}
+	unistr = Malloc(unistr_size);
+	Utf8ToUni(unistr, unistr_size, &line[string_start], StrLen(&line[string_start]));
+
+	// ANSI に変換する
+	str_size = CalcUniToStr(unistr);
+	if (str_size == 0)
+	{
+		str_size = 1;
+		str = Malloc(1);
+		str[0] = 0;
+	}
+	else
+	{
+		str = Malloc(str_size);
+		UniToStr(str, str_size, unistr);
+	}
+
+	if (StrCmpi(name, "PREFIX") == 0)
+	{
+		// プレフィックスが指定された
+		StrCpy(prefix, prefix_size, str);
+		Trim(prefix);
+
+		if (StrCmpi(prefix, "$") == 0 || StrCmpi(prefix, "NULL") == 0)
+		{
+			prefix[0] = 0;
+		}
+
+		Free(name);
+		Free(str);
+		Free(unistr);
+
+		return NULL;
+	}
+
+	name2_size = StrLen(name) + StrLen(prefix) + 2;
+	name2 = ZeroMalloc(name2_size);
+
+	if (prefix[0] != 0)
+	{
+		StrCat(name2, name2_size, prefix);
+		StrCat(name2, name2_size, "@");
+	}
+
+	StrCat(name2, name2_size, name);
+
+	Free(name);
+
+	// TABLE を作成する
+	t = Malloc(sizeof(TABLE));
+	StrUpper(name2);
+	t->name = name2;
+	t->str = str;
+	t->unistr = unistr;
+
+	return t;
+}
+
+// 文字列のアンエスケープ
+void UnescapeStr(char *src)
+{
+	UINT i, len, wp;
+	char *tmp;
+	// 引数チェック
+	if (src == NULL)
+	{
+		return;
+	}
+	
+	len = StrLen(src);
+	tmp = Malloc(len + 1);
+	wp = 0;
+	for (i = 0;i < len;i++)
+	{
+		if (src[i] == '\\')
+		{
+			i++;
+			switch (src[i])
+			{
+			case 0:
+				goto FINISH;
+			case '\\':
+				tmp[wp++] = '\\';
+				break;
+			case ' ':
+				tmp[wp++] = ' ';
+				break;
+			case 'n':
+			case 'N':
+				tmp[wp++] = '\n';
+				break;
+			case 'r':
+			case 'R':
+				tmp[wp++] = '\r';
+				break;
+			case 't':
+			case 'T':
+				tmp[wp++] = '\t';
+				break;
+			}
+		}
+		else
+		{
+			tmp[wp++] = src[i];
+		}
+	}
+FINISH:
+	tmp[wp++] = 0;
+	StrCpy(src, 0, tmp);
+	Free(tmp);
+}
+
+// テーブルを解放する
+void FreeTable()
+{
+	UINT i, num;
+	TABLE **tables;
+	if (TableList == NULL)
+	{
+		return;
+	}
+
+	TrackingDisable();
+
+	num = LIST_NUM(TableList);
+	tables = ToArray(TableList);
+	for (i = 0;i < num;i++)
+	{
+		TABLE *t = tables[i];
+		Free(t->name);
+		Free(t->str);
+		Free(t->unistr);
+		Free(t);
+	}
+	ReleaseList(TableList);
+	TableList = NULL;
+	Free(tables);
+
+	Zero(old_table_name, sizeof(old_table_name));
+
+	TrackingEnable();
+}
+
+// バッファから文字列テーブルを読み込む
+bool LoadTableFromBuf(BUF *b)
+{
+	char *tmp;
+	char prefix[MAX_SIZE];
+	// 引数チェック
+	if (b == NULL)
+	{
+		return false;
+	}
+
+	// すでにテーブルがある場合は削除する
+	FreeTable();
+
+	// リストを作成する
+	TableList = NewList(CmpTableName);
+
+	Zero(prefix, sizeof(prefix));
+
+	// バッファの内容を 1 行ずつ読んでいく
+	while (true)
+	{
+		TABLE *t;
+		tmp = CfgReadNextLine(b);
+		if (tmp == NULL)
+		{
+			break;
+		}
+		t = ParseTableLine(tmp, prefix, sizeof(prefix));
+		if (t != NULL)
+		{
+			// 登録する
+			Insert(TableList, t);
+		}
+		Free(tmp);
+	}
+
+	return true;
+}
+
+// Unicode 文字列キャッシュファイル名の生成
+void GenerateUnicodeCacheFileName(wchar_t *name, UINT size, wchar_t *strfilename, UINT strfilesize, UCHAR *filehash)
+{
+	wchar_t tmp[MAX_SIZE];
+	wchar_t hashstr[64];
+	wchar_t hashtemp[MAX_SIZE];
+	wchar_t exe[MAX_SIZE];
+	UCHAR hash[SHA1_SIZE];
+	// 引数チェック
+	if (name == NULL || strfilename == NULL || filehash == NULL)
+	{
+		return;
+	}
+
+	GetExeDirW(exe, sizeof(exe));
+	UniStrCpy(hashtemp, sizeof(hashtemp), strfilename);
+	BinToStrW(tmp, sizeof(tmp), filehash, MD5_SIZE);
+	UniStrCat(hashtemp, sizeof(hashtemp), tmp);
+	UniStrCat(hashtemp, sizeof(hashtemp), exe);
+	UniStrLower(hashtemp);
+
+	Hash(hash, hashtemp, UniStrLen(hashtemp) * sizeof(wchar_t), true);
+	BinToStrW(hashstr, sizeof(hashstr), hash, 4);
+	UniFormat(tmp, sizeof(tmp), UNICODE_CACHE_FILE, hashstr);
+	UniStrLower(tmp);
+
+#ifndef	OS_WIN32
+	UniStrCpy(exe, sizeof(exe), L"/tmp");
+#else	// OS_WIN32
+	StrToUni(exe, sizeof(exe), MsGetTempDir());
+#endif	// OS_WIN32
+
+	UniFormat(name, size, L"%s/%s", exe, tmp);
+	NormalizePathW(name, size, name);
+}
+
+// Unicode キャッシュの保存
+void SaveUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash)
+{
+	UNICODE_CACHE c;
+	BUF *b;
+	UINT i;
+	IO *io;
+	wchar_t name[MAX_PATH];
+	UCHAR binhash[MD5_SIZE];
+	// 引数チェック
+	if (strfilename == NULL || hash == NULL)
+	{
+		return;
+	}
+
+	Zero(&c, sizeof(c));
+	UniToStr(c.StrFileName, sizeof(c.StrFileName), strfilename);
+	c.StrFileSize = strfilesize;
+	GetMachineName(c.MachineName, sizeof(c.MachineName));
+	c.OsType = GetOsInfo()->OsType;
+	Copy(c.hash, hash, MD5_SIZE);
+
+#ifdef	OS_UNIX
+	GetCurrentCharSet(c.CharSet, sizeof(c.CharSet));
+#else	// OS_UNIX
+	{
+		UINT id = MsGetThreadLocale();
+		Copy(c.CharSet, &id, sizeof(id));
+	}
+#endif	// OS_UNIX
+
+	b = NewBuf();
+	WriteBuf(b, &c, sizeof(c));
+
+	WriteBufInt(b, LIST_NUM(TableList));
+	for (i = 0;i < LIST_NUM(TableList);i++)
+	{
+		TABLE *t = LIST_DATA(TableList, i);
+		WriteBufInt(b, StrLen(t->name));
+		WriteBuf(b, t->name, StrLen(t->name));
+		WriteBufInt(b, StrLen(t->str));
+		WriteBuf(b, t->str, StrLen(t->str));
+		WriteBufInt(b, UniStrLen(t->unistr));
+		WriteBuf(b, t->unistr, UniStrLen(t->unistr) * sizeof(wchar_t));
+	}
+
+	Hash(binhash, b->Buf, b->Size, false);
+	WriteBuf(b, binhash, MD5_SIZE);
+
+	GenerateUnicodeCacheFileName(name, sizeof(name), strfilename, strfilesize, hash);
+
+	io = FileCreateW(name);
+	if (io != NULL)
+	{
+		SeekBuf(b, 0, 0);
+		BufToFile(io, b);
+		FileClose(io);
+	}
+
+	FreeBuf(b);
+}
+
+// Unicode キャッシュの読み込み
+bool LoadUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash)
+{
+	UNICODE_CACHE c, t;
+	BUF *b;
+	UINT i, num;
+	IO *io;
+	wchar_t name[MAX_PATH];
+	UCHAR binhash[MD5_SIZE];
+	UCHAR binhash_2[MD5_SIZE];
+	// 引数チェック
+	if (strfilename == NULL || hash == NULL)
+	{
+		return false;
+	}
+
+	GenerateUnicodeCacheFileName(name, sizeof(name), strfilename, strfilesize, hash);
+
+	io = FileOpenW(name, false);
+	if (io == NULL)
+	{
+		return false;
+	}
+
+	b = FileToBuf(io);
+	if (b == NULL)
+	{
+		FileClose(io);
+		return false;
+	}
+
+	SeekBuf(b, 0, 0);
+	FileClose(io);
+
+	Hash(binhash, b->Buf, b->Size >= MD5_SIZE ? (b->Size - MD5_SIZE) : 0, false);
+	Copy(binhash_2, ((UCHAR *)b->Buf) + (b->Size >= MD5_SIZE ? (b->Size - MD5_SIZE) : 0), MD5_SIZE);
+	if (Cmp(binhash, binhash_2, MD5_SIZE) != 0)
+	{
+		FreeBuf(b);
+		return false;
+	}
+
+	Zero(&c, sizeof(c));
+	UniToStr(c.StrFileName, sizeof(c.StrFileName), strfilename);
+	c.StrFileSize = strfilesize;
+	DisableNetworkNameCache();
+	GetMachineName(c.MachineName, sizeof(c.MachineName));
+	EnableNetworkNameCache();
+	c.OsType = GetOsInfo()->OsType;
+	Copy(c.hash, hash, MD5_SIZE);
+
+#ifdef	OS_UNIX
+	GetCurrentCharSet(c.CharSet, sizeof(c.CharSet));
+#else	// OS_UNIX
+	{
+		UINT id = MsGetThreadLocale();
+		Copy(c.CharSet, &id, sizeof(id));
+	}
+#endif	// OS_UNIX
+
+	Zero(&t, sizeof(t));
+	ReadBuf(b, &t, sizeof(t));
+
+	if (Cmp(&c, &t, sizeof(UNICODE_CACHE)) != 0)
+	{
+		FreeBuf(b);
+		return false;
+	}
+
+	num = ReadBufInt(b);
+
+	FreeTable();
+	TableList = NewList(CmpTableName);
+
+	for (i = 0;i < num;i++)
+	{
+		UINT len;
+		TABLE *t = ZeroMalloc(sizeof(TABLE));
+
+		len = ReadBufInt(b);
+		t->name = ZeroMalloc(len + 1);
+		ReadBuf(b, t->name, len);
+
+		len = ReadBufInt(b);
+		t->str = ZeroMalloc(len + 1);
+		ReadBuf(b, t->str, len);
+
+		len = ReadBufInt(b);
+		t->unistr = ZeroMalloc((len + 1) * sizeof(wchar_t));
+		ReadBuf(b, t->unistr, len * sizeof(wchar_t));
+
+		Add(TableList, t);
+	}
+
+	FreeBuf(b);
+
+	Sort(TableList);
+
+	return true;
+}
+
+// 文字列テーブルを読み込む
+bool LoadTableMain(wchar_t *filename)
+{
+	BUF *b;
+	UINT64 t1, t2;
+	UCHAR hash[MD5_SIZE];
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return false;
+	}
+
+	if (MayaquaIsMinimalMode())
+	{
+		return true;
+	}
+
+	if (UniStrCmpi(old_table_name, filename) == 0)
+	{
+		// すでに読み込まれている
+		return true;
+	}
+
+	t1 = Tick64();
+
+	// ファイルを開く
+	b = ReadDumpW(filename);
+	if (b == NULL)
+	{
+		char tmp[MAX_SIZE];
+		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.)");
+		Alert(tmp, NULL);
+		exit(0);
+		return false;
+	}
+
+	Hash(hash, b->Buf, b->Size, false);
+
+	if (LoadUnicodeCache(filename, b->Size, hash) == false)
+	{
+		if (LoadTableFromBuf(b) == false)
+		{
+			FreeBuf(b);
+			return false;
+		}
+
+		SaveUnicodeCache(filename, b->Size, hash);
+
+		Debug("Unicode Source: strtable.stb\n");
+	}
+	else
+	{
+		Debug("Unicode Source: unicode_cache\n");
+	}
+
+	FreeBuf(b);
+
+	SetLocale(_UU("DEFAULE_LOCALE"));
+
+	UniStrCpy(old_table_name, sizeof(old_table_name), filename);
+
+	t2 = Tick64();
+
+	if (StrCmpi(_SS("STRTABLE_ID"), STRTABLE_ID) != 0)
+	{
+		char tmp[MAX_SIZE];
+		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.)");
+		Alert(tmp, NULL);
+		exit(0);
+		return false;
+	}
+
+	Debug("Unicode File Read Cost: %u (%u Lines)\n", (UINT)(t2 - t1), LIST_NUM(TableList));
+
+	return true;
+}
+bool LoadTable(char *filename)
+{
+	wchar_t *filename_a = CopyStrToUni(filename);
+	bool ret = LoadTableW(filename_a);
+
+	Free(filename_a);
+
+	return ret;
+}
+bool LoadTableW(wchar_t *filename)
+{
+	bool ret;
+	BUF *b;
+	wchar_t replace_name[MAX_PATH];
+
+	Zero(replace_name, sizeof(replace_name));
+
+	TrackingDisable();
+
+	b = ReadDump("@table_name.txt");
+	if (b != NULL)
+	{
+		char *s = CfgReadNextLine(b);
+		if (s != NULL)
+		{
+			if (IsEmptyStr(s) == false)
+			{
+				StrToUni(replace_name, sizeof(replace_name), s);
+				filename = replace_name;
+			}
+
+			Free(s);
+		}
+		FreeBuf(b);
+	}
+
+	ret = LoadTableMain(filename);
+
+	TrackingEnable();
+
+	return ret;
+}
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Table.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Table.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Table.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,143 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Table.h
+// Table.c のヘッダ
+
+#ifndef	TABLE_H
+#define	TABLE_H
+
+#define	UNICODE_CACHE_FILE		L".unicode_cache_%s.dat"
+
+// 言語定数
+#define SE_LANG_JAPANESE			0	// 日本語
+#define SE_LANG_ENGLISH				1	// 英語
+#define SE_LANG_CHINESE_ZH			2	// 中文 (簡体字)
+
+
+// 文字列テーブル
+struct TABLE
+{
+	char *name;
+	char *str;
+	wchar_t *unistr;
+};
+
+// Unicode キャッシュ構造体
+typedef struct UNICODE_CACHE
+{
+	char StrFileName[256];	// 文字列ファイル名
+	UINT StrFileSize;		// 文字列ファイルサイズ
+	char MachineName[256];	// マシン名
+	UINT OsType;			// OS の種類
+	UCHAR hash[MD5_SIZE];	// ハッシュ
+	UCHAR CharSet[64];		// 文字コードの種類
+} UNICODE_CACHE;
+
+// マクロ
+#define	_SS(name)		(GetTableStr((char *)(name)))
+#define	_UU(name)		(GetTableUniStr((char *)(name)))
+#define	_II(name)		(GetTableInt((char *)(name)))
+#define	_E(name)		(GetUniErrorStr((UINT)(name)))
+#define	_EA(name)		(GetErrorStr((UINT)(name)))
+#define _GETLANG()		(_II("LANG"))
+
+
+// 関数プロトタイプ
+bool LoadTable(char *filename);
+bool LoadTableW(wchar_t *filename);
+bool LoadTableMain(wchar_t *filename);
+bool LoadTableFromBuf(BUF *b);
+void FreeTable();
+TABLE *ParseTableLine(char *line, char *prefix, UINT prefix_size);
+void UnescapeStr(char *src);
+int CmpTableName(void *p1, void *p2);
+TABLE *FindTable(char *name);
+TOKEN_LIST *GetTableNameStartWith(char *str);
+char *GetTableStr(char *name);
+wchar_t *GetTableUniStr(char *name);
+char *GetErrorStr(UINT err);
+wchar_t *GetUniErrorStr(UINT err);
+UINT GetTableInt(char *name);
+void GenerateUnicodeCacheFileName(wchar_t *name, UINT size, wchar_t *strfilename, UINT strfilesize, UCHAR *filehash);
+void SaveUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash);
+bool LoadUnicodeCache(wchar_t *strfilename, UINT strfilesize, UCHAR *hash);
+
+#endif	// TABLE_H
+
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tick64.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tick64.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tick64.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,370 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Tick64.c
+// 64bit リアルタイムクロックプログラム
+
+#ifdef	WIN32
+#include <windows.h>
+#endif	// WIN32
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <locale.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+static TICK64 *tk64 = NULL;
+static EVENT *halt_tick_event = NULL;
+
+// 高解像度時刻を取得
+UINT64 TickHighres64()
+{
+	UINT64 ret = 0;
+
+#ifdef	OS_WIN32
+
+	ret = (UINT64)(MsGetHiResTimeSpan(MsGetHiResCounter()) * 1000.0f);
+
+#else	// OS_WIN32
+
+	return Tick64();
+
+#endif	// OS_WIN32
+
+	return ret;
+}
+
+// Tick 値を時刻に変換
+UINT64 Tick64ToTime64(UINT64 tick)
+{
+	UINT64 ret = 0;
+	if (tick == 0)
+	{
+		return 0;
+	}
+	LockList(tk64->AdjustTime);
+	{
+		UINT i;
+		for (i = 0;i < LIST_NUM(tk64->AdjustTime);i++)
+		{
+			ADJUST_TIME *t = LIST_DATA(tk64->AdjustTime, i);
+			if (t->Tick <= tick)
+			{
+				ret = t->Time + (tick - t->Tick);
+			}
+		}
+	}
+	UnlockList(tk64->AdjustTime);
+	if (ret == 0)
+	{
+		ret++;
+	}
+	return ret;
+}
+
+// Tick 値を時刻に変換
+UINT64 TickToTime(UINT64 tick)
+{
+	return Tick64ToTime64(tick);
+}
+
+// Tick 値を取得
+UINT64 Tick64()
+{
+#ifdef	OS_WIN32
+	return Win32FastTick64();
+#else	// OS_WIN32
+	UINT64 tick64;
+	if (tk64 == NULL)
+	{
+		return 0;
+	}
+	Lock(tk64->TickLock);
+	{
+		tick64 = tk64->Tick;
+	}
+	Unlock(tk64->TickLock);
+	return tick64;
+#endif	// OS_WIN32
+}
+
+// リアルタイムクロック測定用スレッド
+void Tick64Thread(THREAD *thread, void *param)
+{
+	UINT n = 0;
+	bool first = false;
+	bool create_first_entry = true;
+	UINT tick_span;
+	// 引数チェック
+	if (thread == NULL)
+	{
+		return;
+	}
+
+#ifdef	OS_WIN32
+
+	// Win32 スレッドの優先順位を上げる
+	MsSetThreadPriorityRealtime();
+
+	tick_span = TICK64_SPAN_WIN32;
+
+#else	// OS_WIN32
+
+	// POSIX スレッドの優先順位を上げる
+	UnixSetThreadPriorityRealtime();
+
+	tick_span = TICK64_SPAN;
+
+#endif	// OS_WIN32
+
+	while (true)
+	{
+		UINT tick;
+		UINT64 tick64;
+
+#ifndef	OS_WIN32
+		tick = TickRealtime();		// 現在のシステムクロックを取得
+
+		if (tk64->LastTick > tick)
+		{
+			if ((tk64->LastTick - tick) >= (UINT64)0x0fffffff)
+			{
+				// tick の値が 1 周した
+				tk64->RoundCount++;
+			}
+			else
+			{
+				// tick の値が逆戻りした (システム管理者がハードウェア時計を変更した)
+				// 通常これは 1 秒以内の誤差として発生する
+				tick = tk64->LastTick;
+			}
+		}
+		tk64->LastTick = tick;
+
+		tick64 = (UINT64)tk64->RoundCount * (UINT64)4294967296LL + (UINT64)tick;
+
+		Lock(tk64->TickLock);
+		{
+			if (tk64->TickStart == 0)
+			{
+				tk64->TickStart = tick64;
+			}
+			tick64 = tk64->Tick = tick64 - tk64->TickStart + (UINT64)1;
+		}
+		Unlock(tk64->TickLock);
+#else	// OS_WIN32
+		tick64 = Win32FastTick64();
+		tick = (UINT)tick64;
+#endif	// OS_WIN32
+
+		if (create_first_entry)
+		{
+			ADJUST_TIME *t = ZeroMalloc(sizeof(ADJUST_TIME));
+			t->Tick = tick64;
+			t->Time = SystemTime64();
+			tk64->Tick64WithTime64 = tick64;
+			tk64->Time64 = t->Time;
+			Add(tk64->AdjustTime, t);
+
+			// 初期化完了を通知
+			NoticeThreadInit(thread);
+			create_first_entry = false;
+		}
+
+		// 時刻補正
+		n += tick_span;
+		if (n >= 1000 || first == false)
+		{
+			UINT64 now = SystemTime64();
+
+			if (now < tk64->Time64 ||
+				Diff64((now - tk64->Time64) + tk64->Tick64WithTime64, tick64) >= tick_span)
+			{
+				ADJUST_TIME *t = ZeroMalloc(sizeof(ADJUST_TIME));
+				LockList(tk64->AdjustTime);
+				{
+					t->Tick = tick64;
+					t->Time = now;
+					Add(tk64->AdjustTime, t);
+					Debug("Adjust Time: Tick = %I64u, Time = %I64u\n",
+						t->Tick, t->Time);
+
+					// 時計が狂っているシステムでメモリを無限に食わないように
+					if (LIST_NUM(tk64->AdjustTime) > MAX_ADJUST_TIME)
+					{
+						// 2 個目を削除する
+						ADJUST_TIME *t2 = LIST_DATA(tk64->AdjustTime, 1);
+
+						Delete(tk64->AdjustTime, t2);
+
+						Debug("NUM_ADJUST TIME: %u\n", LIST_NUM(tk64->AdjustTime));
+
+						Free(t2);
+					}
+				}
+				UnlockList(tk64->AdjustTime);
+				tk64->Time64 = now;
+				tk64->Tick64WithTime64 = tick64;
+			}
+			first = true;
+			n = 0;
+		}
+
+		if (tk64->Halt)
+		{
+			break;
+		}
+
+#ifdef	OS_WIN32
+		Wait(halt_tick_event, tick_span);
+#else	// OS_WIN32
+		SleepThread(tick_span);
+#endif	// OS_WIN32
+	}
+}
+
+// 2 つの 64 bit 整数の差の絶対値を取得
+UINT64 Diff64(UINT64 a, UINT64 b)
+{
+	if (a > b)
+	{
+		return a - b;
+	}
+	else
+	{
+		return b - a;
+	}
+}
+
+// Tick64 の初期化
+void InitTick64()
+{
+	if (tk64 != NULL)
+	{
+		// すでに初期化されている
+		return;
+	}
+
+	halt_tick_event = NewEvent();
+
+	// 構造体の初期化
+	tk64 = ZeroMalloc(sizeof(TICK64));
+	tk64->TickLock = NewLock();
+	tk64->AdjustTime = NewList(NULL);
+
+	// スレッドの作成
+	tk64->Thread = NewThread(Tick64Thread, NULL);
+	WaitThreadInit(tk64->Thread);
+}
+
+// Tick64 の解放
+void FreeTick64()
+{
+	UINT i;
+	if (tk64 == NULL)
+	{
+		// 初期化されていない
+		return;
+	}
+
+	// 終了処理
+	tk64->Halt = true;
+	Set(halt_tick_event);
+	WaitThread(tk64->Thread, INFINITE);
+	ReleaseThread(tk64->Thread);
+
+	// 解放処理
+	for (i = 0;i < LIST_NUM(tk64->AdjustTime);i++)
+	{
+		ADJUST_TIME *t = LIST_DATA(tk64->AdjustTime, i);
+		Free(t);
+	}
+	ReleaseList(tk64->AdjustTime);
+	DeleteLock(tk64->TickLock);
+	Free(tk64);
+	tk64 = NULL;
+
+	ReleaseEvent(halt_tick_event);
+	halt_tick_event = NULL;
+}
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tick64.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tick64.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tick64.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,127 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Tick64.h
+// Tick64.c のヘッダ
+
+#ifndef	TICK64_H
+#define	TICK64_H
+
+// 最大の補正リストエントリ数
+#define	MAX_ADJUST_TIME				5000
+
+// 補正リストエントリ
+struct ADJUST_TIME
+{
+	UINT64 Tick;
+	UINT64 Time;
+};
+
+// TICK64 構造体
+struct TICK64
+{
+	THREAD *Thread;
+	UINT64 Tick;
+	UINT64 TickStart;
+	UINT64 Time64;
+	UINT64 Tick64WithTime64;
+	UINT LastTick;
+	UINT RoundCount;
+	LOCK *TickLock;
+	volatile bool Halt;
+	LIST *AdjustTime;
+};
+
+// 定数
+#define	TICK64_SPAN			10		// 測定間隔 (通常は 10ms以下)
+#define	TICK64_SPAN_WIN32	1000	// Win32 での測定間隔
+#define	TICK64_ADJUST_SPAN	5000	// この値以上時計がずれたら補正する
+
+// 関数プロトタイプ
+void InitTick64();
+void FreeTick64();
+void Tick64Thread(THREAD *thread, void *param);
+UINT64 Tick64();
+UINT64 Diff64(UINT64 a, UINT64 b);
+UINT64 Tick64ToTime64(UINT64 tick);
+UINT64 TickToTime(UINT64 tick);
+UINT64 TickHighres64();
+
+#endif	// TICK64_H
+
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tracking.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tracking.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tracking.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,966 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Tracking.c
+// オブジェクト追跡モジュール
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+// グローバル変数
+static LOCK *obj_lock;
+static LOCK *obj_id_lock;
+static UINT obj_id;
+static LOCK *cs_lock;
+static bool disable_tracking = false;
+static TRACKING_LIST **hashlist;
+
+static bool do_not_get_callstack;
+
+// 追跡を有効にする
+void TrackingEnable()
+{
+	disable_tracking = false;
+}
+
+// 追跡を無効にする
+void TrackingDisable()
+{
+	disable_tracking = true;
+}
+
+// 追跡が有効かどうか取得
+bool IsTrackingEnabled()
+{
+	return !disable_tracking;
+}
+
+// メモリデバッグメニュー
+void MemoryDebugMenu()
+{
+	char tmp[MAX_SIZE];
+	TOKEN_LIST *t;
+	char *cmd;
+	Print("Mayaqua Kernel Memory Debug Tools\n"
+		"Copyright (C) SoftEther Corporation. All Rights Reserved.\n\n");
+	g_memcheck = false;
+	while (true)
+	{
+		Print("debug>");
+		GetLine(tmp, sizeof(tmp));
+		t = ParseToken(tmp, " \t");
+		if (t->NumTokens == 0)
+		{
+			FreeToken(t);
+			DebugPrintAllObjects();
+			continue;
+		}
+		cmd = t->Token[0];
+		if (!StrCmpi(cmd, "?"))
+		{
+			DebugPrintCommandList();
+		}
+		else if (!StrCmpi(cmd, "a"))
+		{
+			DebugPrintAllObjects();
+		}
+		else if (!StrCmpi(cmd, "i"))
+		{
+			if (t->NumTokens == 1)
+			{
+				Print("Usage: i <obj_id>\n\n");
+			}
+			else
+			{
+				DebugPrintObjectInfo(ToInt(t->Token[1]));
+			}
+		}
+		else if (!StrCmpi(cmd, "q"))
+		{
+			break;
+		}
+		else if (ToInt(cmd) != 0)
+		{
+			DebugPrintObjectInfo(ToInt(t->Token[0]));
+		}
+		else
+		{
+			Print("Command Not Found,\n\n");
+		}
+		FreeToken(t);
+	}
+	FreeToken(t);
+	g_memcheck = true;
+}
+
+// オブジェクトを時間順にソートする
+int SortObjectView(void *p1, void *p2)
+{
+	TRACKING_OBJECT *o1, *o2;
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	o1 = *(TRACKING_OBJECT **)p1;
+	o2 = *(TRACKING_OBJECT **)p2;
+	if (o1 == NULL || o2 == NULL)
+	{
+		return 0;
+	}
+
+	if (o1->Id > o2->Id)
+	{
+		return 1;
+	}
+	else if (o1->Id == o2->Id)
+	{
+		return 0;
+	}
+	return -1;
+}
+
+// オブジェクト情報の表示
+void PrintObjectInfo(TRACKING_OBJECT *o)
+{
+	SYSTEMTIME t;
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	UINT64ToSystem(&t, o->CreatedDate);
+	GetDateTimeStrMilli(tmp, sizeof(tmp), &t);
+
+	Print("    TRACKING_OBJECT ID: %u\n"
+		"  TRACKING_OBJECT TYPE: %s\n"
+		"      ADDRESS: 0x%p\n"
+		"  TRACKING_OBJECT SIZE: %u bytes\n"
+		" CREATED DATE: %s\n",
+		o->Id, o->Name, UINT64_TO_POINTER(o->Address), o->Size, tmp);
+
+	PrintCallStack(o->CallStack);
+}
+
+// オブジェクト情報を表示する
+void DebugPrintObjectInfo(UINT id)
+{
+	UINT i;
+	TRACKING_OBJECT *o;
+
+	// 検索
+	o = NULL;
+	LockTrackingList();
+	{
+		for (i = 0;i < TRACKING_NUM_ARRAY;i++)
+		{
+			if (hashlist[i] != NULL)
+			{
+				TRACKING_LIST *t = hashlist[i];
+
+				while (true)
+				{
+					if (t->Object->Id == id)
+					{
+						o = t->Object;
+						break;
+					}
+
+					if (t->Next == NULL)
+					{
+						break;
+					}
+
+					t = t->Next;
+				}
+
+				if (o != NULL)
+				{
+					break;
+				}
+			}
+		}
+	}
+	UnlockTrackingList();
+
+	if (o == NULL)
+	{
+		// ID が発見できなかった
+		Print("obj_id %u Not Found.\n\n", id);
+		return;
+	}
+
+	PrintObjectInfo(o);
+	Print("\n");
+}
+
+// オブジェクトのサマリーの表示
+void PrintObjectList(TRACKING_OBJECT *o)
+{
+	char tmp[MAX_SIZE];
+	SYSTEMTIME t;
+	UINT64ToSystem(&t, o->CreatedDate);
+	GetTimeStrMilli(tmp, sizeof(tmp), &t);
+	TrackGetObjSymbolInfo(o);
+	Print("%-4u - [%-6s] %s 0x%p size=%-5u %11s %u\n",
+		o->Id, o->Name, tmp, UINT64_TO_POINTER(o->Address), o->Size, o->FileName, o->LineNumber);
+}
+
+// すべてのオブジェクトの表示
+void DebugPrintAllObjects()
+{
+	UINT i;
+	LIST *view;
+
+	// リスト作成
+	view = NewListFast(SortObjectView);
+	LockTrackingList();
+	{
+		for (i = 0;i < TRACKING_NUM_ARRAY;i++)
+		{
+			if (hashlist[i] != NULL)
+			{
+				TRACKING_LIST *t = hashlist[i];
+
+				while (true)
+				{
+					Add(view, t->Object);
+
+					if (t->Next == NULL)
+					{
+						break;
+					}
+
+					t = t->Next;
+				}
+			}
+		}
+	}
+	UnlockTrackingList();
+
+	// ソート
+	Sort(view);
+
+	// 描画
+	for (i = 0;i < LIST_NUM(view);i++)
+	{
+		TRACKING_OBJECT *o = (TRACKING_OBJECT *)LIST_DATA(view, i);
+		PrintObjectList(o);
+	}
+
+	// リスト解放
+	ReleaseList(view);
+
+	Print("\n");
+}
+
+// コマンド一覧
+void DebugPrintCommandList()
+{
+	Print(
+		"a - All Objects\n"
+		"i - Object Information\n"
+		"? - Help\n"
+		"q - Quit\n\n"
+		);
+}
+
+// メモリの使用状態を表示する
+void PrintMemoryStatus()
+{
+	MEMORY_STATUS s;
+	GetMemoryStatus(&s);
+	Print("MEMORY STATUS:\n"
+		" NUM_OF_MEMORY_BLOCKS: %u\n"
+		" SIZE_OF_TOTAL_MEMORY: %u bytes\n",
+		s.MemoryBlocksNum, s.MemorySize);
+}
+
+// メモリの使用状態を取得する
+void GetMemoryStatus(MEMORY_STATUS *status)
+{
+	UINT i, num, size;
+	// 引数チェック
+	if (status == NULL)
+	{
+		return;
+	}
+
+	LockTrackingList();
+	{
+		size = num = 0;
+
+		for (i = 0;i < TRACKING_NUM_ARRAY;i++)
+		{
+			if (hashlist[i] != NULL)
+			{
+				TRACKING_LIST *t = hashlist[i];
+
+				while (true)
+				{
+					TRACKING_OBJECT *o = t->Object;
+
+					if (StrCmpi(o->Name, "MEM") == 0)
+					{
+						num++;
+						size += o->Size;
+					}
+
+					if (t->Next == NULL)
+					{
+						break;
+					}
+
+					t = t->Next;
+				}
+			}
+		}
+	}
+	UnlockTrackingList();
+
+	status->MemoryBlocksNum = num;
+	status->MemorySize = size;
+}
+
+// オブジェクトからシンボル情報を取得する
+void TrackGetObjSymbolInfo(TRACKING_OBJECT *o)
+{
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	if (!(o->LineNumber == 0 && o->FileName[0] == 0))
+	{
+		return;
+	}
+
+	if (o->CallStack != NULL)
+	{
+		GetCallStackSymbolInfo(o->CallStack);
+		if (StrLen(o->CallStack->filename) != 0 && o->CallStack->line != 0)
+		{
+			StrCpy(o->FileName, sizeof(o->FileName), o->CallStack->filename);
+			o->LineNumber = o->CallStack->line;
+		}
+	}
+}
+
+// 新しいオブジェクトを追跡リストに入れる
+void TrackNewObj(UINT64 addr, char *name, UINT size)
+{
+	TRACKING_OBJECT *o;
+	UINT new_id;
+	// 引数チェック
+	if (addr == 0 || name == NULL)
+	{
+		return;
+	}
+
+	if (IsMemCheck() == false)
+	{
+		// リリースモードでは追跡しない
+		return;
+	}
+
+	if (disable_tracking)
+	{
+		return;
+	}
+
+	// 新しい ID の生成
+	OSLock(obj_id_lock);
+	{
+		new_id = ++obj_id;
+	}
+	OSUnlock(obj_id_lock);
+
+	o = OSMemoryAlloc(sizeof(TRACKING_OBJECT));
+	o->Id = new_id;
+	o->Address = addr;
+	o->Name = name;
+	o->Size = size;
+	o->CreatedDate = LocalTime64();
+	o->CallStack = WalkDownCallStack(GetCallStack(), 2);
+
+	o->FileName[0] = 0;
+	o->LineNumber = 0;
+
+	LockTrackingList();
+	{
+		InsertTrackingList(o);
+	}
+	UnlockTrackingList();
+}
+
+// 追跡リストからオブジェクトを削除する
+void TrackDeleteObj(UINT64 addr)
+{
+	TRACKING_OBJECT *o;
+	// 引数チェック
+	if (addr == 0)
+	{
+		return;
+	}
+
+	if (IsMemCheck() == false)
+	{
+		// リリースモードでは追跡しない
+		return;
+	}
+
+	if (disable_tracking)
+	{
+		return;
+	}
+
+	LockTrackingList();
+	{
+		o = SearchTrackingList(addr);
+		if (o == NULL)
+		{
+			UnlockTrackingList();
+
+			if (IsDebug())
+			{
+				printf("TrackDeleteObj: 0x%x is not Object!!\n", (void *)addr);
+			}
+			return;
+		}
+		DeleteTrackingList(o, true);
+	}
+	UnlockTrackingList();
+}
+
+// 追跡しているオブジェクトのサイズを変更する
+void TrackChangeObjSize(UINT64 addr, UINT size, UINT64 new_addr)
+{
+	TRACKING_OBJECT *o;
+	// 引数チェック
+	if (addr == 0)
+	{
+		return;
+	}
+
+	if (IsMemCheck() == false)
+	{
+		// リリースモードでは追跡しない
+		return;
+	}
+
+	if (disable_tracking)
+	{
+		return;
+	}
+
+	LockTrackingList();
+	{
+		o = SearchTrackingList(addr);
+		if (o == NULL)
+		{
+			UnlockTrackingList();
+			return;
+		}
+
+		DeleteTrackingList(o, false);
+
+		o->Size = size;
+		o->Address = new_addr;
+
+		InsertTrackingList(o);
+	}
+	UnlockTrackingList();
+}
+
+// メモリアドレス比較関数
+int CompareTrackingObject(const void *p1, const void *p2)
+{
+	TRACKING_OBJECT *o1, *o2;
+	// 引数チェック
+	if (p1 == NULL || p2 == NULL)
+	{
+		return 0;
+	}
+	o1 = *(TRACKING_OBJECT **)p1;
+	o2 = *(TRACKING_OBJECT **)p2;
+	if (o1 == NULL || o2 == NULL)
+	{
+		return 0;
+	}
+
+	if (o1->Address > o2->Address)
+	{
+		return 1;
+	}
+	if (o1->Address == o2->Address)
+	{
+		return 0;
+	}
+	return -1;
+}
+
+// オブジェクトをトラッキングリストから検索
+TRACKING_OBJECT *SearchTrackingList(UINT64 Address)
+{
+	UINT i;
+	// 引数チェック
+	if (Address == 0)
+	{
+		return NULL;
+	}
+
+	i = TRACKING_HASH(Address);
+
+	if (hashlist[i] != NULL)
+	{
+		TRACKING_LIST *tt = hashlist[i];
+
+		while (true)
+		{
+			if (tt->Object->Address == Address)
+			{
+				return tt->Object;
+			}
+
+			tt = tt->Next;
+
+			if (tt == NULL)
+			{
+				break;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+// オブジェクトをトラッキングリストから削除
+void DeleteTrackingList(TRACKING_OBJECT *o, bool free_object_memory)
+{
+	UINT i;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	i = TRACKING_HASH(o->Address);
+
+	if (hashlist[i] != NULL)
+	{
+		TRACKING_LIST *ft = NULL;
+
+		if (hashlist[i]->Object == o)
+		{
+			ft = hashlist[i];
+			hashlist[i] = hashlist[i]->Next;
+		}
+		else
+		{
+			TRACKING_LIST *tt = hashlist[i];
+			TRACKING_LIST *prev = NULL;
+
+			while (true)
+			{
+				if (tt->Object == o)
+				{
+					prev->Next = tt->Next;
+					ft = tt;
+					break;
+				}
+
+				if (tt->Next == NULL)
+				{
+					break;
+				}
+
+				prev = tt;
+				tt = tt->Next;
+			}
+		}
+
+		if (ft != NULL)
+		{
+			OSMemoryFree(ft);
+
+			if (free_object_memory)
+			{
+				FreeCallStack(o->CallStack);
+				OSMemoryFree(o);
+			}
+		}
+	}
+}
+
+// オブジェクトをトラッキングリストに挿入
+void InsertTrackingList(TRACKING_OBJECT *o)
+{
+	UINT i;
+	TRACKING_LIST *t;
+	// 引数チェック
+	if (o == NULL)
+	{
+		return;
+	}
+
+	t = OSMemoryAlloc(sizeof(TRACKING_LIST));
+	t->Object = o;
+	t->Next = NULL;
+
+	i = TRACKING_HASH(o->Address);
+
+	if (hashlist[i] == NULL)
+	{
+		hashlist[i] = t;
+	}
+	else
+	{
+		TRACKING_LIST *tt = hashlist[i];
+		while (true)
+		{
+			if (tt->Next == NULL)
+			{
+				tt->Next = t;
+				break;
+			}
+
+			tt = tt->Next;
+		}
+	}
+}
+
+// トラッキングリストのロック
+void LockTrackingList()
+{
+	OSLock(obj_lock);
+}
+
+// トラッキングリストのロック解除
+void UnlockTrackingList()
+{
+	OSUnlock(obj_lock);
+}
+
+// トラッキングの初期化
+void InitTracking()
+{
+	UINT i;
+	CALLSTACK_DATA *s;
+
+	// ハッシュリスト初期化
+	hashlist = (TRACKING_LIST **)OSMemoryAlloc(sizeof(TRACKING_LIST *) * TRACKING_NUM_ARRAY);
+
+	for (i = 0;i < TRACKING_NUM_ARRAY;i++)
+	{
+		hashlist[i] = NULL;
+	}
+
+	obj_id = 0;
+
+	// ロック作成
+	obj_lock = OSNewLock();
+	obj_id_lock = OSNewLock();
+	cs_lock = OSNewLock();
+
+	s = GetCallStack();
+	if (s == NULL)
+	{
+		do_not_get_callstack = true;
+	}
+	else
+	{
+		do_not_get_callstack = false;
+		FreeCallStack(s);
+	}
+}
+
+// トラッキングの解放
+void FreeTracking()
+{
+	UINT i;
+	// ロック削除
+	OSDeleteLock(obj_lock);
+	OSDeleteLock(obj_id_lock);
+	OSDeleteLock(cs_lock);
+	cs_lock = NULL;
+	obj_id_lock = NULL;
+	obj_lock = NULL;
+
+	// すべての要素を解放
+	for (i = 0;i < TRACKING_NUM_ARRAY;i++)
+	{
+		if (hashlist[i] != NULL)
+		{
+			TRACKING_LIST *t = hashlist[i];
+
+			while (true)
+			{
+				TRACKING_LIST *t2 = t;
+				TRACKING_OBJECT *o = t->Object;
+
+				FreeCallStack(o->CallStack);
+				OSMemoryFree(o);
+
+				t = t->Next;
+
+				OSMemoryFree(t2);
+
+				if (t == NULL)
+				{
+					break;
+				}
+			}
+		}
+	}
+
+	// リスト解放
+	OSMemoryFree(hashlist);
+}
+
+// コールスタックを表示する
+void PrintCallStack(CALLSTACK_DATA *s)
+{
+	char tmp[MAX_SIZE * 2];
+
+	GetCallStackStr(tmp, sizeof(tmp), s);
+	Print("%s", tmp);
+}
+
+// コールスタックを文字列に変換する
+void GetCallStackStr(char *str, UINT size, CALLSTACK_DATA *s)
+{
+	char tmp[MAX_SIZE];
+	char tmp2[MAX_SIZE];
+	char tmp3[MAX_SIZE];
+	UINT num, i;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	if (s == NULL)
+	{
+		StrCpy(str, size, "(Unknown)\n");
+	}
+	else
+	{
+		num = 0;
+		str[0] = 0;
+		while (true)
+		{
+			if (s == NULL)
+			{
+				break;
+			}
+
+			GetCallStackSymbolInfo(s);
+
+			if (s->name == NULL)
+			{
+				Format(tmp, sizeof(tmp), "0x%p ---", UINT64_TO_POINTER(s->offset));
+			}
+			else
+			{
+				Format(tmp, sizeof(tmp), "0x%p %s() + 0x%02x",
+					(void *)s->offset, s->name, UINT64_TO_POINTER(s->disp));
+			}
+			for (i = 0;i < num;i++)
+			{
+				tmp2[i] = ' ';
+			}
+			tmp2[i] = '\0';
+			StrCpy(tmp3, sizeof(tmp3), tmp2);
+			StrCat(tmp3, sizeof(tmp3), tmp);
+			Format(tmp, sizeof(tmp), "%-55s %11s %u\n", tmp3, s->filename, s->line);
+			StrCat(str, size, tmp);
+			num++;
+			s = s->next;
+		}
+	}
+}
+
+// 現在のコールスタックの取得
+CALLSTACK_DATA *GetCallStack()
+{
+	CALLSTACK_DATA *s;
+	if (do_not_get_callstack)
+	{
+		// コールスタックは取得しない
+		return NULL;
+	}
+
+	OSLock(cs_lock);
+	{
+		// コールスタックの取得
+		s = OSGetCallStack();
+	}
+	OSUnlock(cs_lock);
+	if (s == NULL)
+	{
+		return NULL;
+	}
+
+	// コールスタックを 3 つ分だけ下降する
+	s = WalkDownCallStack(s, 3);
+
+	return s;
+}
+
+// コールスタックのシンボル情報を取得
+bool GetCallStackSymbolInfo(CALLSTACK_DATA *s)
+{
+	bool ret;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return false;
+	}
+
+	OSLock(cs_lock);
+	{
+		ret = OSGetCallStackSymbolInfo(s);
+	}
+	OSUnlock(cs_lock);
+
+	return ret;
+}
+
+// コールスタックを指定された数だけ下降する
+CALLSTACK_DATA *WalkDownCallStack(CALLSTACK_DATA *s, UINT num)
+{
+	CALLSTACK_DATA *cs, *tmp;
+	UINT i;
+	// 引数チェック
+	if (s == NULL)
+	{
+		return NULL;
+	}
+
+	cs = s;
+	i = 0;
+
+	while (true)
+	{
+		if (i >= num)
+		{
+			return cs;
+		}
+		i++;
+		tmp = cs;
+		cs = tmp->next;
+		OSMemoryFree(tmp->name);
+		OSMemoryFree(tmp);
+
+		if (cs == NULL)
+		{
+			return NULL;
+		}
+	}
+}
+
+// コールスタックの解放
+void FreeCallStack(CALLSTACK_DATA *s)
+{
+	// 引数チェック
+	if (s == NULL)
+	{
+		return;
+	}
+
+	while (true)
+	{
+		CALLSTACK_DATA *next = s->next;
+		OSMemoryFree(s->name);
+		OSMemoryFree(s);
+		if (next == NULL)
+		{
+			break;
+		}
+		s = next;
+	}
+}
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tracking.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tracking.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Tracking.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,164 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Tracking.h
+// Tracking.c のヘッダ
+
+#ifndef	TRACKING_H
+#define	TRACKING_H
+
+// 配列の数
+#define	TRACKING_NUM_ARRAY	1048576
+
+// ポインタから配列番号をハッシュ
+#define	TRACKING_HASH(p)	(UINT)(((((UINT64)(p)) / (UINT64)(sizeof(void *))) % ((UINT64)TRACKING_NUM_ARRAY)))
+
+// コールスタック
+struct CALLSTACK_DATA
+{
+	bool symbol_cache;
+	UINT64 offset, disp;
+	char *name;
+	struct CALLSTACK_DATA *next;
+	char filename[MAX_PATH];
+	UINT line;
+};
+
+// オブジェクト
+struct TRACKING_OBJECT
+{
+	UINT Id;
+	char *Name;
+	UINT64 Address;
+	UINT Size;
+	UINT64 CreatedDate;
+	CALLSTACK_DATA *CallStack;
+	char FileName[MAX_PATH];
+	UINT LineNumber;
+};
+
+// メモリの使用状態
+struct MEMORY_STATUS
+{
+	UINT MemoryBlocksNum;
+	UINT MemorySize;
+};
+
+// トラッキングリスト
+struct TRACKING_LIST
+{
+	struct TRACKING_LIST *Next;
+	struct TRACKING_OBJECT *Object;
+};
+
+CALLSTACK_DATA *GetCallStack();
+bool GetCallStackSymbolInfo(CALLSTACK_DATA *s);
+void FreeCallStack(CALLSTACK_DATA *s);
+CALLSTACK_DATA *WalkDownCallStack(CALLSTACK_DATA *s, UINT num);
+void GetCallStackStr(char *str, UINT size, CALLSTACK_DATA *s);
+void PrintCallStack(CALLSTACK_DATA *s);
+void InitTracking();
+void FreeTracking();
+int CompareTrackingObject(const void *p1, const void *p2);
+void LockTrackingList();
+void UnlockTrackingList();
+void InsertTrackingList(TRACKING_OBJECT *o);
+void DeleteTrackingList(TRACKING_OBJECT *o, bool free_object_memory);
+TRACKING_OBJECT *SearchTrackingList(UINT64 Address);
+
+void TrackNewObj(UINT64 addr, char *name, UINT size);
+void TrackGetObjSymbolInfo(TRACKING_OBJECT *o);
+void TrackDeleteObj(UINT64 addr);
+void TrackChangeObjSize(UINT64 addr, UINT size, UINT64 new_addr);
+
+void GetMemoryStatus(MEMORY_STATUS *status);
+void PrintMemoryStatus();
+void MemoryDebugMenu();
+int SortObjectView(void *p1, void *p2);
+void DebugPrintAllObjects();
+void DebugPrintCommandList();
+void PrintObjectList(TRACKING_OBJECT *o);
+void PrintObjectInfo(TRACKING_OBJECT *o);
+void DebugPrintObjectInfo(UINT id);
+
+void TrackingEnable();
+void TrackingDisable();
+bool IsTrackingEnabled();
+
+#endif	// TRACKING_H
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/TunTap.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/TunTap.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/TunTap.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,308 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+#ifndef	TUNTAP_H
+#define	TUNTAP_H
+
+#ifdef	UNIX_LINUX
+
+// -----------------------------------------------------------------
+// Linux 用 tap ヘッダ
+// -----------------------------------------------------------------
+/*
+ *  Universal TUN/TAP device driver.
+ *  Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  $Id: if_tun.h,v 1.2 2001/10/31 15:27:57 arjanv Exp $
+ */
+
+#ifndef __IF_TUN_H
+#define __IF_TUN_H
+
+/* Uncomment to enable debugging */
+/* #define TUN_DEBUG 1 */
+
+
+
+/* Read queue size */
+#define TUN_READQ_SIZE  10
+
+/* TUN device flags */
+#define TUN_TUN_DEV     0x0001  
+#define TUN_TAP_DEV     0x0002
+#define TUN_TYPE_MASK   0x000f
+
+#define TUN_FASYNC      0x0010
+#define TUN_NOCHECKSUM  0x0020
+#define TUN_NO_PI       0x0040
+#define TUN_ONE_QUEUE   0x0080
+#define TUN_PERSIST     0x0100  
+
+/* Ioctl defines */
+#define TUNSETNOCSUM  _IOW('T', 200, int) 
+#define TUNSETDEBUG   _IOW('T', 201, int) 
+#define TUNSETIFF     _IOW('T', 202, int) 
+#define TUNSETPERSIST _IOW('T', 203, int) 
+#define TUNSETOWNER   _IOW('T', 204, int)
+
+/* TUNSETIFF ifr flags */
+#define IFF_TUN         0x0001
+#define IFF_TAP         0x0002
+#define IFF_NO_PI       0x1000
+#define IFF_ONE_QUEUE   0x2000
+
+struct tun_pi {
+        unsigned short flags;
+        unsigned short proto;
+};
+#define TUN_PKT_STRIP   0x0001
+
+#endif /* __IF_TUN_H */
+#else	// UNIX_LINUX
+
+#ifdef	UNIX_SOLARIS
+
+// -----------------------------------------------------------------
+// Solaris 用 tap ヘッダ
+// -----------------------------------------------------------------
+/*
+ *  Universal TUN/TAP device driver.
+ *
+ *  Multithreaded STREAMS tun pseudo device driver.
+ *
+ *  Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  $Id: if_tun.h,v 1.4 2000/05/01 12:23:27 maxk Exp $
+ */
+
+#ifndef _SYS_IF_TUN_H
+#define _SYS_IF_TUN_H
+
+#ifdef _KERNEL
+/* Uncomment to enable debuging */
+/* #define TUN_DEBUG 1 */
+
+#ifdef TUN_DEBUG
+#define DBG      cmn_err
+#else
+#define DBG( a... )
+#endif
+
+/* PPA structure, one per TUN iface */ 
+struct tunppa {
+  unsigned int id;              /* Iface number         */
+  queue_t *rq;                  /* Control Stream RQ    */
+  struct tunstr * p_str;        /* Protocol Streams     */
+}; 
+#define TUNMAXPPA       20
+
+/* Stream structure, one per Stream */
+struct tunstr {
+  struct tunstr *s_next;        /* next in streams list */
+  struct tunstr *p_next;        /* next in ppa list */
+  queue_t *rq;                  /* pointer to rq */
+
+  struct tunppa *ppa;           /* assigned PPA */
+  u_long flags;                 /* flags */
+  u_long state;                 /* DL state */
+  u_long sap;                   /* bound sap */
+  u_long minor;                 /* minor device number */
+};
+
+/* Flags */
+#define TUN_CONTROL     0x0001
+
+#define TUN_RAW         0x0100
+#define TUN_FAST        0x0200
+
+#define TUN_ALL_PHY     0x0010
+#define TUN_ALL_SAP     0x0020
+#define TUN_ALL_MUL     0x0040
+
+#define SNIFFER(a) ( (a & TUN_ALL_SAP) || (a & TUN_ALL_PHY) )
+
+struct tundladdr {
+  u_short sap;
+};
+#define TUN_ADDR_LEN    (sizeof(struct tundladdr))
+
+#define TUN_QUEUE       0
+#define TUN_DROP        1
+
+#endif /* _KERNEL */
+
+/* IOCTL defines */
+#define TUNNEWPPA       (('T'<<16) | 0x0001)
+#define TUNSETPPA       (('T'<<16) | 0x0002)
+
+#endif  /* _SYS_IF_TUN_H */
+
+#else	// UNIX_SOLARIS
+
+#ifdef	UNIX_BSD
+
+// -----------------------------------------------------------------
+// FreeBSD 用 tap ヘッダ
+// -----------------------------------------------------------------
+/*      $NetBSD: if_tun.h,v 1.5 1994/06/29 06:36:27 cgd Exp $   */
+
+/*
+ * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
+ * Nottingham University 1987.
+ *
+ * This source may be freely distributed, however I would be interested
+ * in any changes that are made.
+ *
+ * This driver takes packets off the IP i/f and hands them up to a
+ * user process to have its wicked way with. This driver has it's
+ * roots in a similar driver written by Phil Cockcroft (formerly) at
+ * UCL. This driver is based much more on read/write/select mode of
+ * operation though.
+ *
+ * $FreeBSD: src/sys/net/if_tun.h,v 1.17 2000/01/23 01:47:12 brian Exp $
+ */
+
+#ifndef _NET_IF_TUN_H_
+#define _NET_IF_TUN_H_
+
+/* Refer to if_tunvar.h for the softc stuff */
+
+/* Maximum transmit packet size (default) */
+#define TUNMTU          1500
+
+/* Maximum receive packet size (hard limit) */
+#define TUNMRU          16384
+
+struct tuninfo {
+        int     baudrate;               /* linespeed */
+        short   mtu;                    /* maximum transmission unit */
+        u_char  type;                   /* ethernet, tokenring, etc. */
+        u_char  dummy;                  /* place holder */
+};
+
+/* ioctl's for get/set debug */
+#define TUNSDEBUG       _IOW('t', 90, int)
+#define TUNGDEBUG       _IOR('t', 89, int)
+#define TUNSIFINFO      _IOW('t', 91, struct tuninfo)
+#define TUNGIFINFO      _IOR('t', 92, struct tuninfo)
+#define TUNSLMODE       _IOW('t', 93, int)
+#define TUNSIFMODE      _IOW('t', 94, int)
+#define TUNSIFPID       _IO('t', 95)
+#define TUNSIFHEAD      _IOW('t', 96, int)
+#define TUNGIFHEAD      _IOR('t', 97, int)
+
+#endif /* !_NET_IF_TUN_H_ */
+
+#else	// UNIX_BSD
+
+#ifdef	UNIX_MACOS
+
+// -----------------------------------------------------------------
+// MacOS 用 tap ヘッダ
+// -----------------------------------------------------------------
+
+#else	// UNIX_MACOS
+
+#endif	// UNIX_MACOS
+
+#endif	// UNIX_BSD
+
+#endif	// UNIX_SOLARIS
+
+#endif	// UNIX_LINUX
+
+#endif	// TUNTAP_H
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Unix.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Unix.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Unix.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,2438 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Unix.c
+// UNIX 依存コード
+
+#ifdef	UNIX
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+// MacOS X 用の struct statfs
+#ifdef	UNIX_MACOS
+typedef struct fsid { int32_t val[2]; } fsid_t;
+struct statfs {
+        short   f_otype;                /* TEMPORARY SHADOW COPY OF f_type */
+        short   f_oflags;               /* TEMPORARY SHADOW COPY OF f_flags */
+        long    f_bsize;                /* fundamental file system block size */
+        long    f_iosize;               /* optimal transfer block size */
+        long    f_blocks;               /* total data blocks in file system */
+        long    f_bfree;                /* free blocks in fs */
+        long    f_bavail;               /* free blocks avail to non-superuser */
+        long    f_files;                /* total file nodes in file system */
+        long    f_ffree;                /* free file nodes in fs */
+        fsid_t  f_fsid;                 /* file system id */
+        uid_t   f_owner;                /* user that mounted the filesystem */
+        short   f_reserved1;    /* spare for later */
+        short   f_type;                 /* type of filesystem */
+    long        f_flags;                /* copy of mount exported flags */
+        long    f_reserved2[2]; /* reserved for future use */
+        char    f_fstypename[15]; /* fs type name */
+        char    f_mntonname[90];  /* directory on which mounted */
+        char    f_mntfromname[90];/* mounted filesystem */
+};
+#endif	// UNIX_MACOS
+
+// Solaris 用の scandir() 関数
+#ifdef	UNIX_SOLARIS
+#define scandir local_scandir
+#define	alphasort local_alphasort
+
+/*******************************************
+ * Copyright Free の互換ルーチン (local_scandir)
+ * コピー元: http://www005.upp.so-net.ne.jp/yoga/compile.html
+ *******************************************/
+
+int local_scandir(const char *dir, struct dirent ***namelist,
+            int (*select)(const struct dirent *),
+            int (*compar)(const struct dirent **, const struct dirent **))
+{
+  DIR *d;
+  struct dirent *entry;
+  register int i=0;
+  size_t entrysize;
+
+  if ((d=opendir(dir)) == NULL)
+     return(-1);
+
+  *namelist=NULL;
+  while ((entry=readdir(d)) != NULL)
+  {
+    if (select == NULL || (select != NULL && (*select)(entry)))
+    {
+      *namelist=(struct dirent **)realloc((void *)(*namelist),
+                 (size_t)((i+1)*sizeof(struct dirent *)));
+	if (*namelist == NULL) return(-1);
+	entrysize=sizeof(struct dirent)-sizeof(entry->d_name)+strlen(entry->d_name)+1;
+	(*namelist)[i]=(struct dirent *)malloc(entrysize);
+	if ((*namelist)[i] == NULL) return(-1);
+	memcpy((*namelist)[i], entry, entrysize);
+	i++;
+    }
+  }
+  if (closedir(d)) return(-1);
+  if (i == 0) return(-1);
+  if (compar != NULL)
+    qsort((void *)(*namelist), (size_t)i, sizeof(struct dirent *), compar);
+    
+  return(i);
+}
+
+int local_alphasort(const struct dirent **a, const struct dirent **b)
+{
+  return(strcmp((*a)->d_name, (*b)->d_name));
+}
+
+
+#endif	// UNIX_SOLARIS
+
+// UNIX 用スレッドデータ
+typedef struct UNIXTHREAD
+{
+	pthread_t thread;
+	bool finished;
+} UNIXTHREAD;
+
+// UNIX 用スレッド起動情報
+typedef struct UNIXTHREADSTARTUPINFO
+{
+	THREAD_PROC *thread_proc;
+	void *param;
+	THREAD *thread;
+} UNIXTHREADSTARTUPINFO;
+
+// UNIX 用スレッド関数プロトタイプ
+void *UnixDefaultThreadProc(void *param);
+
+// 現在のプロセス ID
+static pid_t current_process_id = 0;
+
+// UNIX 用ファイル I/O データ
+typedef struct UNIXIO
+{
+	int fd;
+	bool write_mode;
+} UNIXIO;
+
+// UNIX 用ロックファイルデータ
+typedef struct UNIXLOCKFILE
+{
+	char FileName[MAX_SIZE];
+	int fd;
+} UNIXLOCKFILE;
+
+// UNIX 用イベントデータ
+typedef struct UNIXEVENT
+{
+	pthread_mutex_t mutex;
+	pthread_cond_t cond;
+	bool signal;
+} UNIXEVENT;
+
+static pthread_mutex_t get_time_lock;
+static pthread_mutex_t malloc_lock;
+static bool high_process = false;
+
+static bool unix_svc_terminate = false;
+static int solaris_sleep_p1 = -1, solaris_sleep_p2 = -1;
+
+// ディスパッチテーブルの作成
+OS_DISPATCH_TABLE *UnixGetDispatchTable()
+{
+	static OS_DISPATCH_TABLE t =
+	{
+		UnixInit,
+		UnixFree,
+		UnixMemoryAlloc,
+		UnixMemoryReAlloc,
+		UnixMemoryFree,
+		UnixGetTick,
+		UnixGetSystemTime,
+		UnixInc32,
+		UnixDec32,
+		UnixSleep,
+		UnixNewLock,
+		UnixLock,
+		UnixUnlock,
+		UnixDeleteLock,
+		UnixInitEvent,
+		UnixSetEvent,
+		UnixResetEvent,
+		UnixWaitEvent,
+		UnixFreeEvent,
+		UnixWaitThread,
+		UnixFreeThread,
+		UnixInitThread,
+		UnixThreadId,
+		UnixFileOpen,
+		UnixFileOpenW,
+		UnixFileCreate,
+		UnixFileCreateW,
+		UnixFileWrite,
+		UnixFileRead,
+		UnixFileClose,
+		UnixFileFlush,
+		UnixFileSize,
+		UnixFileSeek,
+		UnixFileDelete,
+		UnixFileDeleteW,
+		UnixMakeDir,
+		UnixMakeDirW,
+		UnixDeleteDir,
+		UnixDeleteDirW,
+		UnixGetCallStack,
+		UnixGetCallStackSymbolInfo,
+		UnixFileRename,
+		UnixFileRenameW,
+		UnixRun,
+		UnixRunW,
+		UnixIsSupportedOs,
+		UnixGetOsInfo,
+		UnixAlert,
+		UnixAlertW,
+		UnixGetProductId,
+		UnixSetHighPriority,
+		UnixRestorePriority,
+		UnixNewSingleInstance,
+		UnixFreeSingleInstance,
+		UnixGetMemInfo,
+		UnixYield,
+	};
+
+	return &t;
+}
+
+// Solaris 用 Sleep の初期化
+void UnixInitSolarisSleep()
+{
+	char tmp[MAX_SIZE];
+
+	UnixNewPipe(&solaris_sleep_p1, &solaris_sleep_p2);
+	read(solaris_sleep_p1, tmp, sizeof(tmp));
+}
+
+// Solaris 用 Sleep の解放
+void UnixFreeSolarisSleep()
+{
+	UnixDeletePipe(solaris_sleep_p1, solaris_sleep_p2);
+	solaris_sleep_p1 = -1;
+	solaris_sleep_p2 = -1;
+}
+
+// Solaris 用 Sleep
+void UnixSolarisSleep(UINT msec)
+{
+	struct pollfd p;
+
+	memset(&p, 0, sizeof(p));
+	p.fd = solaris_sleep_p1;
+	p.events = POLLIN;
+
+	poll(&p, 1, msec == INFINITE ? -1 : (int)msec);
+}
+
+// ディスクの空き容量を取得する
+bool UnixGetDiskFreeW(wchar_t *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)
+{
+	char *path_a = CopyUniToStr(path);
+	bool ret;
+
+	ret = UnixGetDiskFree(path_a, free_size, used_size, total_size);
+
+	Free(path_a);
+
+	return ret;
+}
+bool UnixGetDiskFree(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)
+{
+	char tmp[MAX_PATH];
+	bool ret = false;
+	// 引数チェック
+	if (path == NULL)
+	{
+		return false;
+	}
+
+	NormalizePath(tmp, sizeof(tmp), path);
+
+	while ((ret = UnixGetDiskFreeMain(tmp, free_size, used_size, total_size)) == false)
+	{
+		if (StrCmpi(tmp, "/") == 0)
+		{
+			break;
+		}
+
+		GetDirNameFromFilePath(tmp, sizeof(tmp), tmp);
+	}
+
+	return ret;
+}
+bool UnixGetDiskFreeMain(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)
+{
+#ifndef	USE_STATVFS
+	struct statfs st;
+	char tmp[MAX_PATH];
+	UINT64 v1 = 0, v2 = 0;
+	bool ret = false;
+	// 引数チェック
+	if (path == NULL)
+	{
+		return false;
+	}
+
+	NormalizePath(tmp, sizeof(tmp), path);
+
+	Zero(&st, sizeof(st));
+	if (statfs(tmp, &st) == 0)
+	{
+		v1 = (UINT64)st.f_bsize * (UINT64)st.f_bavail;
+		v2 = (UINT64)st.f_bsize * (UINT64)st.f_blocks;
+		ret = true;
+	}
+
+	if (free_size != NULL)
+	{
+		*free_size = v1;
+	}
+
+	if (total_size != NULL)
+	{
+		*total_size = v2;
+	}
+
+	if (used_size != NULL)
+	{
+		*used_size = v2 - v1;
+	}
+
+	return ret;
+#else	// USE_STATVFS
+	struct statvfs st;
+	char tmp[MAX_PATH];
+	UINT64 v1 = 0, v2 = 0;
+	bool ret = false;
+	// 引数チェック
+	if (path == NULL)
+	{
+		return false;
+	}
+
+	NormalizePath(tmp, sizeof(tmp), path);
+
+	Zero(&st, sizeof(st));
+
+	if (statvfs(tmp, &st) == 0)
+	{
+		v1 = (UINT64)st.f_bsize * (UINT64)st.f_bavail;
+		v2 = (UINT64)st.f_bsize * (UINT64)st.f_blocks;
+		ret = true;
+	}
+
+	if (free_size != NULL)
+	{
+		*free_size = v1;
+	}
+
+	if (total_size != NULL)
+	{
+		*total_size = v2;
+	}
+
+	if (used_size != NULL)
+	{
+		*used_size = v2 - v1;
+	}
+
+	return ret;
+#endif	// USE_STATVFS
+}
+
+// ディレクトリ列挙
+DIRLIST *UnixEnumDirEx(char *dirname, COMPARE *compare)
+{
+	char tmp[MAX_PATH];
+	DIRLIST *d;
+	int n;
+	struct dirent **e;
+	LIST *o;
+	// 引数チェック
+	if (dirname == NULL)
+	{
+		return NULL;
+	}
+
+	o = NewListFast(compare);
+
+	NormalizePath(tmp, sizeof(tmp), dirname);
+
+	if (StrLen(tmp) >= 1 && tmp[StrLen(tmp) - 1] != '/')
+	{
+		StrCat(tmp, sizeof(tmp), "/");
+	}
+
+	e = NULL;
+	n = scandir(tmp, &e, 0, alphasort);
+
+	if (StrLen(tmp) >= 1 && tmp[StrLen(tmp) - 1] == '/')
+	{
+		tmp[StrLen(tmp) - 1] = 0;
+	}
+
+	if (n >= 0 && e != NULL)
+	{
+		UINT i;
+
+		for (i = 0;i < (UINT)n;i++)
+		{
+			char *filename = e[i]->d_name;
+
+			if (filename != NULL)
+			{
+				if (StrCmpi(filename, "..") != 0 && StrCmpi(filename, ".") != 0)
+				{
+					char fullpath[MAX_PATH];
+					struct stat st;
+					Format(fullpath, sizeof(fullpath), "%s/%s", tmp, filename);
+
+					Zero(&st, sizeof(st));
+
+					if (stat(fullpath, &st) == 0)
+					{
+						DIRENT *f = ZeroMalloc(sizeof(DIRENT));
+						SYSTEMTIME t;
+
+						f->Folder = S_ISDIR(st.st_mode) ? true : false;
+						f->FileName = CopyStr(filename);
+						f->FileNameW = CopyUtfToUni(f->FileName);
+
+						Zero(&t, sizeof(t));
+						TimeToSystem(&t, st.st_ctime);
+						f->CreateDate = LocalToSystem64(SystemToUINT64(&t));
+
+						Zero(&t, sizeof(t));
+						TimeToSystem(&t, st.st_mtime);
+						f->UpdateDate = LocalToSystem64(SystemToUINT64(&t));
+
+						if (f->Folder == false)
+						{
+							f->FileSize = st.st_size;
+						}
+
+						Add(o, f);
+					}
+				}
+			}
+
+			free(e[i]);
+		}
+
+		free(e);
+	}
+
+	Sort(o);
+
+	d = ZeroMalloc(sizeof(DIRLIST));
+	d->NumFiles = LIST_NUM(o);
+	d->File = ToArray(o);
+
+	ReleaseList(o);
+
+	return d;
+}
+DIRLIST *UnixEnumDirExW(wchar_t *dirname, COMPARE *compare)
+{
+	char *dirname_a = CopyUniToUtf(dirname);
+	DIRLIST *ret;
+
+	ret = UnixEnumDirEx(dirname_a, compare);
+
+	Free(dirname_a);
+
+	return ret;
+}
+
+// 指定したファイルの実行権限をチェックする
+bool UnixCheckExecAccess(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (access(name, X_OK) == 0)
+	{
+		return true;
+	}
+
+	return false;
+}
+bool UnixCheckExecAccessW(wchar_t *name)
+{
+	char *name_a;
+	bool ret;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	name_a = CopyUniToUtf(name);
+
+	ret = UnixCheckExecAccess(name_a);
+
+	Free(name_a);
+
+	return ret;
+}
+
+// スレッドの優先順位を最高にする
+void UnixSetThreadPriorityRealtime()
+{
+	struct sched_param p;
+	Zero(&p, sizeof(p));
+	p.sched_priority = 255;
+	pthread_setschedparam(pthread_self(), SCHED_RR, &p);
+}
+
+// スレッドの優先順位を低くする
+void UnixSetThreadPriorityLow()
+{
+	struct sched_param p;
+	Zero(&p, sizeof(p));
+	p.sched_priority = 32;
+	pthread_setschedparam(pthread_self(), SCHED_OTHER, &p);
+}
+
+// スレッドの優先順位を高くする
+void UnixSetThreadPriorityHigh()
+{
+	struct sched_param p;
+	Zero(&p, sizeof(p));
+	p.sched_priority = 127;
+	pthread_setschedparam(pthread_self(), SCHED_RR, &p);
+}
+
+// スレッドの優先順位をアイドルにする
+void UnixSetThreadPriorityIdle()
+{
+	struct sched_param p;
+	Zero(&p, sizeof(p));
+	p.sched_priority = 1;
+	pthread_setschedparam(pthread_self(), SCHED_OTHER, &p);
+}
+
+// スレッドの優先順位を標準に戻す
+void UnixRestoreThreadPriority()
+{
+	struct sched_param p;
+	Zero(&p, sizeof(p));
+	p.sched_priority = 64;
+	pthread_setschedparam(pthread_self(), SCHED_OTHER, &p);
+}
+
+// 現在のディレクトリの取得
+void UnixGetCurrentDir(char *dir, UINT size)
+{
+	// 引数チェック
+	if (dir == NULL)
+	{
+		return;
+	}
+
+	getcwd(dir, size);
+}
+void UnixGetCurrentDirW(wchar_t *dir, UINT size)
+{
+	char dir_a[MAX_PATH];
+
+	UnixGetCurrentDir(dir_a, sizeof(dir_a));
+
+	UtfToUni(dir, size, dir_a);
+}
+
+// イールド
+void UnixYield()
+{
+#ifdef UNIX_SOLARIS
+	UnixSolarisSleep(1);
+#else
+	sleep(1);
+#endif
+}
+
+// メモリ情報の取得
+void UnixGetMemInfo(MEMINFO *info)
+{
+	// 引数チェック
+	if (info == NULL)
+	{
+		return;
+	}
+
+	// 知らん！！
+	Zero(info, sizeof(MEMINFO));
+}
+
+// シングルインスタンスの解放
+void UnixFreeSingleInstance(void *data)
+{
+	UNIXLOCKFILE *o;
+	struct flock lock;
+	// 引数チェック
+	if (data == NULL)
+	{
+		return;
+	}
+
+	o = (UNIXLOCKFILE *)data;
+
+	Zero(&lock, sizeof(lock));
+	lock.l_type = F_UNLCK;
+	lock.l_whence = SEEK_SET;
+
+	fcntl(o->fd, F_SETLK, &lock);
+	close(o->fd);
+
+	remove(o->FileName);
+
+	Free(data);
+}
+
+// シングルインスタンスの作成
+void *UnixNewSingleInstance(char *instance_name)
+{
+	UNIXLOCKFILE *ret;
+	char tmp[MAX_SIZE];
+	char name[MAX_SIZE];
+	char dir[MAX_PATH];
+	int fd;
+	struct flock lock;
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		GetExeName(tmp, sizeof(tmp));
+		HashInstanceName(tmp, sizeof(tmp), tmp);
+	}
+	else
+	{
+		StrCpy(tmp, sizeof(tmp), instance_name);
+	}
+
+	GetExeDir(dir, sizeof(dir));
+
+	// ファイル名の生成
+	Format(name, sizeof(name), "%s/.%s", dir, tmp);
+
+	fd = open(name, O_WRONLY);
+	if (fd == -1)
+	{
+		fd = creat(name, 0600);
+	}
+	if (fd == -1)
+	{
+		Format(tmp, sizeof(tmp), "Unable to create %s.", name);
+		Alert(tmp, NULL);
+		exit(0);
+		return NULL;
+	}
+
+	Zero(&lock, sizeof(lock));
+	lock.l_type = F_WRLCK;
+	lock.l_whence = SEEK_SET;
+
+	if (fcntl(fd, F_SETLK, &lock) == -1)
+	{
+		return NULL;
+	}
+	else
+	{
+		ret = ZeroMalloc(sizeof(UNIXLOCKFILE));
+		ret->fd = fd;
+		StrCpy(ret->FileName, sizeof(ret->FileName), name);
+		return (void *)ret;
+	}
+}
+
+// プロセスの優先順位を上げる
+void UnixSetHighPriority()
+{
+	if (high_process == false)
+	{
+		UINT pid = getpid();
+		UINT pgid = getpgid(pid);
+
+		high_process = true;
+		nice(-20);
+
+		setpriority(PRIO_PROCESS, pid, -20);
+		setpriority(PRIO_PGRP, pgid, -20);
+	}
+}
+
+// プロセスの優先順位を戻す
+void UnixRestorePriority()
+{
+	if (high_process != false)
+	{
+		high_process = false;
+		nice(20);
+	}
+}
+
+// プロダクト ID を取得する
+char *UnixGetProductId()
+{
+	return CopyStr("--");
+}
+
+// アラートを表示する
+void UnixAlertW(wchar_t *msg, wchar_t *caption)
+{
+	char *msg8 = CopyUniToUtf(msg);
+	char *caption8 = CopyUniToUtf(caption);
+
+	UnixAlert(msg8, caption8);
+
+	Free(msg8);
+	Free(caption8);
+}
+void UnixAlert(char *msg, char *caption)
+{
+	char *tag =
+		"-- Alert: %s --\n%s\n";
+	// 引数チェック
+	if (msg == NULL)
+	{
+		msg = "Alert";
+	}
+	if (caption == NULL)
+	{
+		caption = "SoftEther UT-VPN Kernel";
+	}
+
+	printf(tag, caption, msg);
+}
+
+// 現在の OS の情報を取得する
+void UnixGetOsInfo(OS_INFO *info)
+{
+	// 引数チェック
+	if (info == NULL)
+	{
+		return;
+	}
+
+	Zero(info, sizeof(OS_INFO));
+	info->OsType = OSTYPE_UNIX_UNKNOWN;
+
+#ifdef	UNIX_SOLARIS
+	info->OsType = OSTYPE_SOLARIS;
+#endif	// UNIX_SOLARIS
+
+#ifdef	UNIX_CYGWIN
+	info->OsType = OSTYPE_CYGWIN;
+#endif	// UNIX_CYGWIN
+
+#ifdef	UNIX_MACOS
+	info->OsType = OSTYPE_MACOS_X;
+#endif	// UNIX_MACOS
+
+#ifdef	UNIX_BSD
+	info->OsType = OSTYPE_BSD;
+#endif	// UNIX_BSD
+
+#ifdef	UNIX_LINUX
+	info->OsType = OSTYPE_LINUX;
+#endif	// UNIX_LINUX
+
+	info->OsServicePack = 0;
+
+	if (info->OsType != OSTYPE_LINUX)
+	{
+		info->OsSystemName = CopyStr("UNIX");
+		info->OsProductName = CopyStr("UNIX");
+	}
+	else
+	{
+		info->OsSystemName = CopyStr("Linux");
+		info->OsProductName = CopyStr("Linux");
+	}
+
+	if (info->OsType == OSTYPE_LINUX)
+	{
+		// Linux の場合 ディストリビューション名を取得する
+		BUF *b;
+		b = ReadDump("/etc/redhat-release");
+		if (b != NULL)
+		{
+			info->OsVersion = CfgReadNextLine(b);
+			info->OsVendorName = CopyStr("Red Hat, Inc.");
+			FreeBuf(b);
+		}
+		else
+		{
+			b = ReadDump("/etc/turbolinux-release");
+			if (b != NULL)
+			{
+				info->OsVersion = CfgReadNextLine(b);
+				info->OsVendorName = CopyStr("Turbolinux, Inc.");
+				FreeBuf(b);
+			}
+			else
+			{
+				info->OsVersion = CopyStr("Unknown Liunx Version");
+				info->OsVendorName = CopyStr("Unknown Vendor");
+			}
+		}
+
+		info->KernelName = CopyStr("Linux Kernel");
+
+		b = ReadDump("/proc/sys/kernel/osrelease");
+		if (b != NULL)
+		{
+			info->KernelVersion = CfgReadNextLine(b);
+			FreeBuf(b);
+		}
+		else
+		{
+			info->KernelVersion = CopyStr("Unknown Version");
+		}
+	}
+	else
+	{
+		// その他の場合
+		info->OsProductName = CopyStr(OsTypeToStr(info->OsType));
+		info->OsVersion = CopyStr("Unknown Version");
+		info->KernelName = CopyStr(OsTypeToStr(info->OsType));
+		info->KernelVersion = CopyStr("Unknown Version");
+	}
+}
+
+// 現在の OS が SoftEther UT-VPN Kernel によってサポートされているかどうか調べる
+bool UnixIsSupportedOs()
+{
+	// すべての起動可能な UNIX OS をサポートしている
+	return true;
+}
+
+// 指定したコマンドを実行する
+bool UnixRunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait)
+{
+	char *filename8 = CopyUniToUtf(filename);
+	char *arg8 = CopyUniToUtf(arg);
+	bool ret = UnixRun(filename8, arg8, hide, wait);
+
+	Free(filename8);
+	Free(arg8);
+
+	return ret;
+}
+bool UnixRun(char *filename, char *arg, bool hide, bool wait)
+{
+	TOKEN_LIST *t;
+	UINT ret;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return false;
+	}
+	if (arg == NULL)
+	{
+		arg = "";
+	}
+
+	// 子プロセス作成
+	ret = fork();
+	if (ret == -1)
+	{
+		// 子プロセス作成失敗
+		return false;
+	}
+
+	if (ret == 0)
+	{
+		Print("", filename, arg);
+		// 子プロセス
+		if (hide)
+		{
+			// 標準入出力を閉じる
+			UnixCloseIO();
+		}
+
+		t = ParseToken(arg, " ");
+		if (t == NULL)
+		{
+			AbortExit();
+		}
+		else
+		{
+			char **args;
+			UINT num_args;
+			UINT i;
+			num_args = t->NumTokens + 2;
+			args = ZeroMalloc(sizeof(char *) * num_args);
+			args[0] = filename;
+			for (i = 1;i < num_args - 1;i++)
+			{
+				args[i] = t->Token[i - 1];
+			}
+			execvp(filename, args);
+			AbortExit();
+		}
+	}
+	else
+	{
+		// 親プロセス
+		pid_t pid = (pid_t)ret;
+
+		if (wait)
+		{
+			int status = 0;
+			// 子プロセスの終了を待機する
+			if (waitpid(pid, &status, 0) == -1)
+			{
+				return false;
+			}
+
+			if (WEXITSTATUS(status) == 0)
+			{
+				return true;
+			}
+			else
+			{
+				return false;
+			}
+		}
+
+		return true;
+	}
+}
+
+// デーモンの初期化
+void UnixDaemon(bool debug_mode)
+{
+	UINT ret;
+
+	if (debug_mode)
+	{
+		// デバッグモード
+		signal(SIGHUP, SIG_IGN);
+		return;
+	}
+
+	ret = fork();
+
+	if (ret == -1)
+	{
+		// エラー
+		return;
+	}
+	else if (ret == 0)
+	{
+		// 子プロセス用に新しいセッションを作成する
+		setsid();
+
+		// 標準入出力をクローズする
+		UnixCloseIO();
+
+		// 不要なシグナルを停止する
+		signal(SIGHUP, SIG_IGN);
+	}
+	else
+	{
+		// 親プロセスを終了する
+		exit(0);
+	}
+}
+
+// 標準入出力をクローズする
+void UnixCloseIO()
+{
+	static bool close_io_first = false;
+
+	// 1 回しか実行できない
+	if (close_io_first)
+	{
+		return;
+	}
+	else
+	{
+		close(0);
+		close(1);
+		close(2);
+		open("/dev/null", O_RDWR);
+		dup2(0, 1);
+		dup2(0, 2);
+		close_io_first = false;
+	}
+}
+
+// ファイル名を変更する
+bool UnixFileRenameW(wchar_t *old_name, wchar_t *new_name)
+{
+	char *old_name8 = CopyUniToUtf(old_name);
+	char *new_name8 = CopyUniToUtf(new_name);
+	bool ret = UnixFileRename(old_name8, new_name8);
+
+	Free(old_name8);
+	Free(new_name8);
+
+	return ret;
+}
+bool UnixFileRename(char *old_name, char *new_name)
+{
+	// 引数チェック
+	if (old_name == NULL || new_name == NULL)
+	{
+		return false;
+	}
+
+	if (rename(old_name, new_name) != 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// コールスタックを取得する
+CALLSTACK_DATA *UnixGetCallStack()
+{
+	// Win32 以外ではサポートされていない
+	return NULL;
+}
+
+// コールスタックからシンボル情報を取得
+bool UnixGetCallStackSymbolInfo(CALLSTACK_DATA *s)
+{
+	// Win32 以外ではサポートされていない
+	return false;
+}
+
+// ディレクトリを削除する
+bool UnixDeleteDirW(wchar_t *name)
+{
+	char *name8 = CopyUniToUtf(name);
+	bool ret = UnixDeleteDir(name8);
+
+	Free(name8);
+
+	return ret;
+}
+bool UnixDeleteDir(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (rmdir(name) != 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ディレクトリを作成する
+bool UnixMakeDirW(wchar_t *name)
+{
+	char *name8 = CopyUniToUtf(name);
+	bool ret = UnixMakeDir(name8);
+
+	Free(name8);
+
+	return ret;
+}
+bool UnixMakeDir(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (mkdir(name, 0700) != 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ファイルを削除する
+bool UnixFileDeleteW(wchar_t *name)
+{
+	bool ret;
+	char *name8 = CopyUniToUtf(name);
+
+	ret = UnixFileDelete(name8);
+
+	Free(name8);
+
+	return ret;
+}
+bool UnixFileDelete(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (remove(name) != 0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ファイルをシークする
+bool UnixFileSeek(void *pData, UINT mode, int offset)
+{
+	UNIXIO *p;
+	UINT ret;
+	// 引数チェック
+	if (pData == NULL)
+	{
+		return 0;
+	}
+	if (mode != FILE_BEGIN && mode != FILE_END && mode != FILE_CURRENT)
+	{
+		return false;
+	}
+
+	p = (UNIXIO *)pData;
+
+	ret = lseek(p->fd, offset, mode);
+
+	if (ret == -1)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ファイルサイズを取得する
+UINT64 UnixFileSize(void *pData)
+{
+	struct stat st;
+	UNIXIO *p;
+	// 引数チェック
+	if (pData == NULL)
+	{
+		return 0;
+	}
+
+	p = (UNIXIO *)pData;
+
+	if (fstat(p->fd, &st) != 0)
+	{
+		return 0;
+	}
+
+	return (UINT64)st.st_size;
+}
+
+// ファイルに書き込む
+bool UnixFileWrite(void *pData, void *buf, UINT size)
+{
+	UNIXIO *p;
+	UINT ret;
+	// 引数チェック
+	if (pData == NULL || buf == NULL || size == 0)
+	{
+		return false;
+	}
+
+	p = (UNIXIO *)pData;
+
+	ret = write(p->fd, buf, size);
+	if (ret != size)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ファイルから読み込む
+bool UnixFileRead(void *pData, void *buf, UINT size)
+{
+	UNIXIO *p;
+	UINT ret;
+	// 引数チェック
+	if (pData == NULL || buf == NULL || size == 0)
+	{
+		return false;
+	}
+
+	p = (UNIXIO *)pData;
+
+	ret = read(p->fd, buf, size);
+	if (ret != size)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ファイルをフラッシュする
+void UnixFileFlush(void *pData)
+{
+	UNIXIO *p;
+	bool write_mode;
+	// 引数チェック
+	if (pData == NULL)
+	{
+		return;
+	}
+
+	p = (UNIXIO *)pData;
+
+	write_mode = p->write_mode;
+
+	if (write_mode)
+	{
+		fsync(p->fd);
+	}
+}
+
+// ファイルを閉じる
+void UnixFileClose(void *pData, bool no_flush)
+{
+	UNIXIO *p;
+	bool write_mode;
+	// 引数チェック
+	if (pData == NULL)
+	{
+		return;
+	}
+
+	p = (UNIXIO *)pData;
+
+	write_mode = p->write_mode;
+
+	if (write_mode && no_flush == false)
+	{
+		fsync(p->fd);
+	}
+
+	close(p->fd);
+
+	UnixMemoryFree(p);
+
+	if (write_mode)
+	{
+		//sync();
+	}
+}
+
+// ファイルを作成する
+void *UnixFileCreateW(wchar_t *name)
+{
+	void *ret;
+	char *name8 = CopyUniToUtf(name);
+
+	ret = UnixFileCreate(name8);
+
+	Free(name8);
+
+	return ret;
+}
+void *UnixFileCreate(char *name)
+{
+	UNIXIO *p;
+	int fd;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	fd = creat(name, 0600);
+	if (fd == -1)
+	{
+		return NULL;
+	}
+
+	// メモリ確保
+	p = UnixMemoryAlloc(sizeof(UNIXIO));
+	p->fd = fd;
+	p->write_mode = true;
+
+	return (void *)p;
+}
+
+// ファイルを開く
+void *UnixFileOpenW(wchar_t *name, bool write_mode, bool read_lock)
+{
+	char *name8 = CopyUniToUtf(name);
+	void *ret;
+
+	ret = UnixFileOpen(name8, write_mode, read_lock);
+
+	Free(name8);
+
+	return ret;
+}
+void *UnixFileOpen(char *name, bool write_mode, bool read_lock)
+{
+	UNIXIO *p;
+	int fd;
+	int mode;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	if (write_mode == false)
+	{
+		mode = O_RDONLY;
+	}
+	else
+	{
+		mode = O_RDWR;
+	}
+
+	// ファイルを開く
+	fd = open(name, mode);
+	if (fd == -1)
+	{
+		return NULL;
+	}
+
+	// メモリ確保
+	p = UnixMemoryAlloc(sizeof(UNIXIO));
+	p->fd = fd;
+	p->write_mode = write_mode;
+
+	return (void *)p;
+}
+
+// 現在のスレッド ID を返す
+UINT UnixThreadId()
+{
+	UINT ret;
+
+	ret = (UINT)pthread_self();
+
+	return ret;
+}
+
+// スレッド関数
+void *UnixDefaultThreadProc(void *param)
+{
+	UNIXTHREAD *ut;
+	UNIXTHREADSTARTUPINFO *info = (UNIXTHREADSTARTUPINFO *)param;
+	if (info == NULL)
+	{
+		return 0;
+	}
+
+	ut = (UNIXTHREAD *)info->thread->pData;
+
+	// スレッド関数の呼び出し
+	info->thread_proc(info->thread, info->param);
+
+	// 終了フラグを立てる
+	ut->finished = true;
+
+	// 参照の解放
+	ReleaseThread(info->thread);
+
+	UnixMemoryFree(info);
+
+	FreeOpenSSLThreadState();
+
+	return 0;
+}
+
+// スレッドの解放
+void UnixFreeThread(THREAD *t)
+{
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+
+	// メモリの解放
+	UnixMemoryFree(t->pData);
+}
+
+// スレッドの終了を待機
+bool UnixWaitThread(THREAD *t)
+{
+	UNIXTHREAD *ut;
+	void *retcode = NULL;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return false;
+	}
+	ut = (UNIXTHREAD *)t->pData;
+	if (ut == NULL)
+	{
+		return false;
+	}
+
+	pthread_join(ut->thread, &retcode);
+
+	return true;
+}
+
+// スレッドの初期化
+bool UnixInitThread(THREAD *t)
+{
+	UNIXTHREAD *ut;
+	UNIXTHREADSTARTUPINFO *info;
+	pthread_attr_t attr;
+	// 引数チェック
+	if (t == NULL || t->thread_proc == NULL)
+	{
+		return false;
+	}
+
+	// スレッドデータ作成
+	ut = UnixMemoryAlloc(sizeof(UNIXTHREAD));
+	Zero(ut, sizeof(UNIXTHREAD));
+
+	// 起動情報作成
+	info = UnixMemoryAlloc(sizeof(UNIXTHREADSTARTUPINFO));
+	Zero(info, sizeof(UNIXTHREADSTARTUPINFO));
+	info->param = t->param;
+	info->thread_proc = t->thread_proc;
+	info->thread = t;
+	AddRef(t->ref);
+
+	// スレッド作成
+	pthread_attr_init(&attr);
+	pthread_attr_setstacksize(&attr, UNIX_THREAD_STACK_SIZE);
+
+	t->pData = (void *)ut;
+
+	if (pthread_create(&ut->thread, &attr, UnixDefaultThreadProc, info) != 0)
+	{
+		// エラー発生
+		t->pData = NULL;
+		Release(t->ref);
+		UnixMemoryFree(ut);
+		UnixMemoryFree(info);
+		pthread_attr_destroy(&attr);
+		return false;
+	}
+
+	pthread_attr_destroy(&attr);
+
+	return true;
+}
+
+// イベントの解放
+void UnixFreeEvent(EVENT *event)
+{
+	UNIXEVENT *ue = (UNIXEVENT *)event->pData;
+	if (ue == NULL)
+	{
+		return;
+	}
+
+	pthread_cond_destroy(&ue->cond);
+	pthread_mutex_destroy(&ue->mutex);
+
+	UnixMemoryFree(ue);
+}
+
+// イベントの待機
+bool UnixWaitEvent(EVENT *event, UINT timeout)
+{
+	UNIXEVENT *ue = (UNIXEVENT *)event->pData;
+	struct timeval now;
+	struct timespec to;
+	bool ret;
+	if (ue == NULL)
+	{
+		return false;
+	}
+
+	pthread_mutex_lock(&ue->mutex);
+	gettimeofday(&now, NULL);
+	to.tv_sec = now.tv_sec + timeout / 1000;
+	to.tv_nsec = now.tv_usec * 1000 + (timeout % 1000) * 1000 * 1000;
+	if ((to.tv_nsec / 1000000000) >= 1)
+	{
+		to.tv_sec += to.tv_nsec / 1000000000;
+		to.tv_nsec = to.tv_nsec % 1000000000;
+	}
+
+	ret = true;
+
+	while (ue->signal == false)
+	{
+		if (timeout != INFINITE)
+		{
+			if (pthread_cond_timedwait(&ue->cond, &ue->mutex, &to))
+			{
+				ret = false;
+				break;
+			}
+		}
+		else
+		{
+			pthread_cond_wait(&ue->cond, &ue->mutex);
+		}
+	}
+	ue->signal = false;
+
+	pthread_mutex_unlock(&ue->mutex);
+
+	return ret;
+}
+
+// イベントのリセット
+void UnixResetEvent(EVENT *event)
+{
+	UNIXEVENT *ue = (UNIXEVENT *)event->pData;
+	if (ue == NULL)
+	{
+		return;
+	}
+
+	pthread_mutex_lock(&ue->mutex);
+	ue->signal = false;
+	pthread_cond_signal(&ue->cond);
+	pthread_mutex_unlock(&ue->mutex);
+}
+
+// イベントのセット
+void UnixSetEvent(EVENT *event)
+{
+	UNIXEVENT *ue = (UNIXEVENT *)event->pData;
+	if (ue == NULL)
+	{
+		return;
+	}
+
+	pthread_mutex_lock(&ue->mutex);
+	ue->signal = true;
+	pthread_cond_signal(&ue->cond);
+	pthread_mutex_unlock(&ue->mutex);
+}
+
+// イベントの初期化
+void UnixInitEvent(EVENT *event)
+{
+	UNIXEVENT *ue = UnixMemoryAlloc(sizeof(UNIXEVENT));
+
+	Zero(ue, sizeof(UNIXEVENT));
+
+	pthread_cond_init(&ue->cond, NULL);
+	pthread_mutex_init(&ue->mutex, NULL);
+	ue->signal = false;
+
+	event->pData = (void *)ue;
+}
+
+// ロックの削除
+void UnixDeleteLock(LOCK *lock)
+{
+	pthread_mutex_t *mutex;
+	// Ready フラグを安全に解除する
+	UnixLock(lock);
+	lock->Ready = false;
+	UnixUnlockEx(lock, true);
+
+	// mutex の削除
+	mutex = (pthread_mutex_t *)lock->pData;
+	pthread_mutex_destroy(mutex);
+
+	// メモリ解放
+	UnixMemoryFree(mutex);
+	UnixMemoryFree(lock);
+}
+
+// ロック解除
+void UnixUnlock(LOCK *lock)
+{
+	UnixUnlockEx(lock, false);
+}
+void UnixUnlockEx(LOCK *lock, bool inner)
+{
+	pthread_mutex_t *mutex;
+	if (lock->Ready == false && inner == false)
+	{
+		// 状態が不正
+		return;
+	}
+	mutex = (pthread_mutex_t *)lock->pData;
+
+	if ((--lock->locked_count) > 0)
+	{
+		return;
+	}
+
+	lock->thread_id = INFINITE;
+
+	pthread_mutex_unlock(mutex);
+
+	return;
+}
+
+// ロック
+bool UnixLock(LOCK *lock)
+{
+	pthread_mutex_t *mutex;
+	UINT thread_id = UnixThreadId();
+	if (lock->Ready == false)
+	{
+		// 状態が不正
+		return false;
+	}
+
+	if (lock->thread_id == thread_id)
+	{
+		lock->locked_count++;
+		return true;
+	}
+
+	mutex = (pthread_mutex_t *)lock->pData;
+
+	pthread_mutex_lock(mutex);
+
+	lock->thread_id = thread_id;
+	lock->locked_count++;
+
+	return true;
+}
+
+// 新しいロックの作成
+LOCK *UnixNewLock()
+{
+	pthread_mutex_t *mutex;
+	// メモリ確保
+	LOCK *lock = UnixMemoryAlloc(sizeof(LOCK));
+
+	// mutex 作成
+	mutex = UnixMemoryAlloc(sizeof(pthread_mutex_t));
+
+	// mutex 初期化
+	pthread_mutex_init(mutex, NULL);
+
+	lock->pData = (void *)mutex;
+	lock->Ready = true;
+
+	lock->thread_id = INFINITE;
+	lock->locked_count = 0;
+
+	return lock;
+}
+
+// スリープ
+void UnixSleep(UINT time)
+{
+	UINT sec = 0, millisec = 0;
+	// 引数チェック
+	if (time == 0)
+	{
+		return;
+	}
+
+	if (time == INFINITE)
+	{
+		// 無限に待機する
+		while (true)
+		{
+#ifdef UNIX_SOLARIS
+			UnixSolarisSleep(time);
+#else
+			sleep(1000000);
+#endif
+		}
+	}
+
+#ifdef UNIX_SOLARIS
+	UnixSolarisSleep(time);
+#else
+
+	// 桁あふれ防止
+	sec = time / 1000;
+	millisec = time % 1000;
+
+	if (sec != 0)
+	{
+		sleep(sec);
+	}
+	if (millisec != 0)
+	{
+		usleep(millisec * 1000);
+	}
+#endif
+}
+
+// デクリメント
+void UnixDec32(UINT *value)
+{
+	if (value != NULL)
+	{
+		(*value)--;
+	}
+}
+
+// インクリメント
+void UnixInc32(UINT *value)
+{
+	if (value != NULL)
+	{
+		(*value)++;
+	}
+}
+
+// システム時刻の取得
+void UnixGetSystemTime(SYSTEMTIME *system_time)
+{
+	time_t now = 0;
+	struct tm tm;
+	struct timeval tv;
+	struct timezone tz;
+	// 引数チェック
+	if (system_time == NULL)
+	{
+		return;
+	}
+
+	pthread_mutex_lock(&get_time_lock);
+
+	Zero(system_time, sizeof(SYSTEMTIME));
+	Zero(&tv, sizeof(tv));
+	Zero(&tz, sizeof(tz));
+
+	time(&now);
+
+	gmtime_r(&now, &tm);
+
+	TmToSystem(system_time, &tm);
+
+	gettimeofday(&tv, &tz);
+
+	system_time->wMilliseconds = tv.tv_usec / 1000;
+
+	pthread_mutex_unlock(&get_time_lock);
+}
+
+// システムタイマの取得 (64bit)
+UINT64 UnixGetTick64()
+{
+#if	defined(OS_WIN32) || defined(CLOCK_REALTIME) || defined(CLOCK_MONOTONIC) || defined(CLOCK_HIGHRES)
+
+	struct timespec t;
+	UINT64 ret;
+	static bool akirame = false;
+
+	if (akirame)
+	{
+		return TickRealtimeManual();
+	}
+
+	Zero(&t, sizeof(t));
+
+	// システムの起動時刻を取得する関数
+	// システムによって実装が異なるので注意
+#ifdef	CLOCK_HIGHRES
+	clock_gettime(CLOCK_HIGHRES, &t);
+#else	// CLOCK_HIGHRES
+#ifdef	CLOCK_MONOTONIC
+	clock_gettime(CLOCK_MONOTONIC, &t);
+#else	// CLOCK_MONOTONIC
+	clock_gettime(CLOCK_REALTIME, &t);
+#endif	// CLOCK_MONOTONIC
+#endif	// CLOCK_HIGHRES
+
+	ret = (UINT64)t.tv_sec * 1000LL + (UINT64)t.tv_nsec / 1000000LL;
+
+	if (akirame == false && ret == 0)
+	{
+		ret = TickRealtimeManual();
+		akirame = true;
+	}
+
+	return ret;
+
+#else
+
+	return TickRealtimeManual();
+
+#endif
+}
+
+// システムタイマの取得
+UINT UnixGetTick()
+{
+	return (UINT)UnixGetTick64();
+}
+
+// メモリの確保
+void *UnixMemoryAlloc(UINT size)
+{
+	void *r;
+	pthread_mutex_lock(&malloc_lock);
+	r = malloc(size);
+	pthread_mutex_unlock(&malloc_lock);
+	return r;
+}
+
+// メモリの再確保
+void *UnixMemoryReAlloc(void *addr, UINT size)
+{
+	void *r;
+	pthread_mutex_lock(&malloc_lock);
+	r = realloc(addr, size);
+	pthread_mutex_unlock(&malloc_lock);
+	return r;
+}
+
+// メモリの解放
+void UnixMemoryFree(void *addr)
+{
+	pthread_mutex_lock(&malloc_lock);
+	free(addr);
+	pthread_mutex_unlock(&malloc_lock);
+}
+
+// SIGCHLD ハンドラ
+void UnixSigChldHandler(int sig)
+{
+	// ゾンビプロセスの回収
+	while (waitpid(-1, NULL, WNOHANG) > 0);
+	signal(SIGCHLD, UnixSigChldHandler);
+}
+
+// UNIX 用ライブラリの初期化
+void UnixInit()
+{
+	UNIXIO *o;
+
+	UnixInitSolarisSleep();
+
+	// グローバルロック
+	pthread_mutex_init(&get_time_lock, NULL);
+	pthread_mutex_init(&malloc_lock, NULL);
+
+	// プロセス ID の取得
+	current_process_id = getpid();
+
+#ifdef	RLIMIT_CORE
+	UnixSetResourceLimit(RLIMIT_CORE, UNIX_MAX_MEMORY);
+#endif	// RLIMIT_CORE
+
+#ifdef	RLIMIT_DATA
+	UnixSetResourceLimit(RLIMIT_DATA, UNIX_MAX_MEMORY);
+#endif	// RLIMIT_DATA
+
+#ifdef	RLIMIT_NOFILE
+	UnixSetResourceLimit(RLIMIT_NOFILE, UNIX_MAX_FD);
+#endif	// RLIMIT_NOFILE
+
+#ifdef	RLIMIT_STACK
+//	UnixSetResourceLimit(RLIMIT_STACK, UNIX_MAX_MEMORY);
+#endif	// RLIMIT_STACK
+
+#ifdef	RLIMIT_RSS
+	UnixSetResourceLimit(RLIMIT_RSS, UNIX_MAX_MEMORY);
+#endif	// RLIMIT_RSS
+
+#ifdef	RLIMIT_LOCKS
+	UnixSetResourceLimit(RLIMIT_LOCKS, UNIX_MAX_LOCKS);
+#endif	// RLIMIT_LOCKS
+
+#ifdef	RLIMIT_MEMLOCK
+	UnixSetResourceLimit(RLIMIT_MEMLOCK, UNIX_MAX_MEMORY);
+#endif	// RLIMIT_MEMLOCK
+
+#ifdef	RLIMIT_NPROC
+	UnixSetResourceLimit(RLIMIT_NPROC, UNIX_MAX_CHILD_PROCESSES);
+#endif	// RLIMIT_NPROC
+
+	// proc ファイルシステムの threads-max に値を書き込む
+	o = UnixFileCreate("/proc/sys/kernel/threads-max");
+	if (o != NULL)
+	{
+		char tmp[128];
+		sprintf(tmp, "%u\n", UNIX_LINUX_MAX_THREADS);
+		UnixFileWrite(o, tmp, strlen(tmp));
+		UnixFileClose(o, false);
+	}
+
+	// 無視するシグナルを設定
+	signal(SIGPIPE, SIG_IGN);
+	signal(SIGALRM, SIG_IGN);
+
+#ifdef	UNIX_BSD
+	signal(64, SIG_IGN);
+#endif	// UNIX_BSD
+
+#ifdef	SIGXFSZ
+	signal(SIGXFSZ, SIG_IGN);
+#endif	// SIGXFSZ
+
+	// 子プロセス回収用シグナルハンドラの設定
+	signal(SIGCHLD, UnixSigChldHandler);
+}
+
+// UNIX 用ライブラリの解放
+void UnixFree()
+{
+	UnixFreeSolarisSleep();
+
+	current_process_id = 0;
+
+	pthread_mutex_destroy(&get_time_lock);
+}
+
+// 占有することができる資源の上限値を調整
+void UnixSetResourceLimit(UINT id, UINT value)
+{
+	struct rlimit t;
+	UINT hard_limit;
+
+	Zero(&t, sizeof(t));
+	getrlimit(id, &t);
+
+	hard_limit = t.rlim_max;
+
+	Zero(&t, sizeof(t));
+	t.rlim_cur = MIN(value, hard_limit);
+	t.rlim_max = hard_limit;
+	setrlimit(id, &t);
+
+	Zero(&t, sizeof(t));
+	t.rlim_cur = value;
+	t.rlim_max = value;
+	setrlimit(id, &t);
+}
+
+// PID ファイル名を生成する
+void UnixGenPidFileName(char *name, UINT size)
+{
+	char exe_name[MAX_PATH];
+	UCHAR hash[MD5_SIZE];
+	char tmp1[64];
+	char dir[MAX_PATH];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	GetExeDir(dir, sizeof(dir));
+
+	GetExeName(exe_name, sizeof(exe_name));
+	StrCat(exe_name, sizeof(exe_name), ":pid_hash");
+	StrUpper(exe_name);
+
+	Hash(hash, exe_name, StrLen(exe_name), false);
+	BinToStr(tmp1, sizeof(tmp1), hash, sizeof(hash));
+
+	Format(name, size, "%s/.pid_%s", dir, tmp1);
+}
+
+// PID ファイルを削除する
+void UnixDeletePidFile()
+{
+	char tmp[MAX_PATH];
+
+	UnixGenPidFileName(tmp, sizeof(tmp));
+
+	UnixFileDelete(tmp);
+}
+
+// PID ファイルに書き込む
+void UnixWritePidFile(UINT pid)
+{
+	char tmp[MAX_PATH];
+	char tmp2[64];
+	IO *o;
+
+	UnixGenPidFileName(tmp, sizeof(tmp));
+	Format(tmp2, sizeof(tmp2), "%u\n", pid);
+
+	o = FileCreate(tmp);
+	if (o != NULL)
+	{
+		FileWrite(o, tmp2, StrLen(tmp2));
+		FileClose(o);
+	}
+}
+
+// PID ファイルを読み込む
+UINT UnixReadPidFile()
+{
+	char tmp[MAX_PATH];
+	BUF *buf;
+
+	UnixGenPidFileName(tmp, sizeof(tmp));
+
+	buf = ReadDump(tmp);
+	if (buf == NULL)
+	{
+		return 0;
+	}
+
+	Zero(tmp, sizeof(tmp));
+	Copy(tmp, buf->Buf, MIN(buf->Size, sizeof(tmp)));
+	FreeBuf(buf);
+
+	return ToInt(tmp);
+}
+
+// サービスの開始
+void UnixStartService(char *name)
+{
+	char *svc_name, *svc_title;
+	char tmp[128];
+	INSTANCE *inst;
+	char exe[MAX_PATH];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	GetExeName(exe, sizeof(exe));
+
+	Format(tmp, sizeof(tmp), SVC_NAME, name);
+	svc_name = _SS(tmp);
+	Format(tmp, sizeof(tmp), SVC_TITLE, name);
+	svc_title = _SS(tmp);
+
+	// すでにサービスが起動していないかどうか調べる
+	inst = NewSingleInstance(NULL);
+	if (inst == NULL)
+	{
+		// すでにサービスが起動している
+		UniPrint(_UU("UNIX_SVC_ALREADY_START"), svc_title, svc_name);
+	}
+	else
+	{
+		int pid;
+		// サービスの起動を開始する
+		UniPrint(_UU("UNIX_SVC_STARTED"), svc_title);
+		FreeSingleInstance(inst);
+
+		// 子プロセスを作成する
+		pid = fork();
+		if (pid == -1)
+		{
+			UniPrint(_UU("UNIX_SVC_ERROR_FORK"), svc_title);
+		}
+		else
+		{
+			if (pid == 0)
+			{
+				// 子プロセス
+				char *param = UNIX_SVC_ARG_EXEC_SVC;
+				char **args;
+
+				// デーモン化する
+				setsid();
+				UnixCloseIO();
+				signal(SIGHUP, SIG_IGN);
+
+				// 引数を準備
+				args = ZeroMalloc(sizeof(char *) * 3);
+				args[0] = exe;
+				args[1] = param;
+				args[2] = NULL;
+
+				execvp(exe, args);
+				AbortExit();
+			}
+			else
+			{
+				// 子プロセス番号をファイルに書き込まない
+//				UnixWritePidFile(pid);
+			}
+		}
+	}
+}
+
+// サービスの停止
+void UnixStopService(char *name)
+{
+	char *svc_name, *svc_title;
+	char tmp[128];
+	INSTANCE *inst;
+	char exe[MAX_PATH];
+	UINT pid;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	GetExeName(exe, sizeof(exe));
+
+	Format(tmp, sizeof(tmp), SVC_NAME, name);
+	svc_name = _SS(tmp);
+	Format(tmp, sizeof(tmp), SVC_TITLE, name);
+	svc_title = _SS(tmp);
+
+	inst = NewSingleInstance(NULL);
+	pid = UnixReadPidFile();
+	if (inst != NULL || pid == 0)
+	{
+		// まだサービスが起動していない
+		UniPrint(_UU("UNIX_SVC_NOT_STARTED"), svc_title, svc_name);
+	}
+	else
+	{
+		int status;
+
+		// サービスを停止する
+		UniPrint(_UU("UNIX_SVC_STOPPING"), svc_title);
+
+		// プロセスを終了する
+		kill(pid, SIGTERM);
+		if (UnixWaitProcessEx(pid, UNIX_SERVICE_STOP_TIMEOUT_2))
+		{
+			UniPrint(_UU("UNIX_SVC_STOPPED"), svc_title);
+		}
+		else
+		{
+			UniPrint(_UU("UNIX_SVC_STOP_FAILED"), svc_title);
+		}
+	}
+
+	FreeSingleInstance(inst);
+}
+
+// プロセスへの停止シグナルのハンドラ
+void UnixSigTermHandler(int signum)
+{
+	if (signum == SIGTERM)
+	{
+		unix_svc_terminate = true;
+	}
+}
+
+// サービス停止用スレッド
+void UnixStopThread(THREAD *t, void *param)
+{
+	SERVICE_FUNCTION *stop = (SERVICE_FUNCTION *)param;
+	// 引数チェック
+	if (t == NULL || param == NULL)
+	{
+		return;
+	}
+
+	stop();
+}
+
+// サービスの内容の実行
+void UnixExecService(char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)
+{
+	char *svc_name, *svc_title;
+	char tmp[128];
+	INSTANCE *inst;
+	UINT yobi_size = 1024 * 128;
+	void *yobi1, *yobi2;
+	// 引数チェック
+	if (start == NULL || stop == NULL || name == NULL)
+	{
+		return;
+	}
+
+	Format(tmp, sizeof(tmp), SVC_NAME, name);
+	svc_name = _SS(tmp);
+	Format(tmp, sizeof(tmp), SVC_TITLE, name);
+	svc_title = _SS(tmp);
+
+	inst = NewSingleInstance(NULL);
+	if (inst != NULL)
+	{
+		THREAD *t;
+
+		yobi1 = ZeroMalloc(yobi_size);
+		yobi2 = ZeroMalloc(yobi_size);
+
+		// 起動
+		UnixWritePidFile(getpid());
+
+		start();
+
+		// 起動完了 別のプロセスから SIGTERM が送られてくるのを待つ
+		signal(SIGTERM, &UnixSigTermHandler);
+		while (unix_svc_terminate == false)
+		{
+			pause();
+		}
+
+		// 停止
+		Free(yobi1);
+		t = NewThread(UnixStopThread, stop);
+		if (t == NULL || (WaitThread(t, UNIX_SERVICE_STOP_TIMEOUT_1) == false))
+		{
+			// 停止用スレッドの作成に失敗したか、タイムアウトした場合は
+			// 強制終了する
+			Free(yobi2);
+			FreeSingleInstance(inst);
+			UnixDeletePidFile();
+			_exit(0);
+		}
+		ReleaseThread(t);
+
+		// PID ファイルを削除
+		UnixDeletePidFile();
+
+		FreeSingleInstance(inst);
+
+		Free(yobi2);
+	}
+}
+
+// 指定した pid のプロセスが存在するかどうか取得する
+bool UnixIsProcess(UINT pid)
+{
+	if (getsid((pid_t)pid) == -1)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// 指定したプロセスの終了を待機する
+bool UnixWaitProcessEx(UINT pid,  UINT timeout)
+{
+	UINT64 start_tick = Tick64();
+	UINT64 end_tick = start_tick + (UINT64)timeout;
+	if (timeout == INFINITE)
+	{
+		end_tick = 0;
+	}
+	while (UnixIsProcess(pid))
+	{
+		if (end_tick != 0)
+		{
+			if (end_tick < Tick64())
+			{
+				return false;
+			}
+		}
+		SleepThread(100);
+	}
+	return true;
+}
+void UnixWaitProcess(UINT pid)
+{
+	UnixWaitProcessEx(pid, INFINITE);
+}
+
+// 起動方法の説明
+void UnixUsage(char *name)
+{
+	char *svc_name, *svc_title;
+	char tmp[128];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	Format(tmp, sizeof(tmp), SVC_NAME, name);
+	svc_name = _SS(tmp);
+	Format(tmp, sizeof(tmp), SVC_TITLE, name);
+	svc_title = _SS(tmp);
+
+	UniPrint(_UU("UNIX_SVC_HELP"), svc_title, svc_name, svc_name, svc_title, svc_name, svc_title);
+}
+
+// UNIX サービスのメイン関数
+UINT UnixService(int argc, char *argv[], char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)
+{
+	// 引数チェック
+	if (name == NULL || start == NULL || stop == NULL)
+	{
+		return 0;
+	}
+
+	if (argc >= 2 && StrCmpi(argv[1], UNIX_SVC_ARG_EXEC_SVC) == 0)
+	{
+		UINT pid;
+		// 子プロセスを生成して開始する
+		// もし子プロセスが正しく終了しなかった場合は再起動する
+
+RESTART_PROCESS:
+		pid = fork();
+		if ((int)pid != -1)
+		{
+			if (pid == 0)
+			{
+				// メイン処理の実行
+				UnixServiceMain(argc, argv, name, start, stop);
+			}
+			else
+			{
+				int status = 0, ret;
+
+				// 子プロセスの終了を待機する
+				ret = waitpid(pid, &status, 0);
+
+				if (WIFEXITED(status) == 0)
+				{
+					// 異常終了した
+					UnixSleep(100);
+					goto RESTART_PROCESS;
+				}
+			}
+		}
+	}
+	else
+	{
+		// 通常に開始する
+		UnixServiceMain(argc, argv, name, start, stop);
+	}
+
+	return 0;
+}
+void UnixServiceMain(int argc, char *argv[], char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop)
+{
+	UINT mode = 0;
+	// Mayaqua の開始
+	InitMayaqua(false, false, argc, argv);
+
+	if (argc >= 2)
+	{
+		if (StrCmpi(argv[1], UNIX_SVC_ARG_START) == 0)
+		{
+			mode = UNIX_SVC_MODE_START;
+		}
+		if (StrCmpi(argv[1], UNIX_SVC_ARG_STOP) == 0)
+		{
+			mode = UNIX_SVC_MODE_STOP;
+		}
+		if (StrCmpi(argv[1], UNIX_SVC_ARG_EXEC_SVC) == 0)
+		{
+			mode = UNIX_SVC_MODE_EXEC_SVC;
+		}
+		if (StrCmpi(argv[1], UNIX_ARG_EXIT) == 0)
+		{
+			mode = UNIX_SVC_MODE_EXIT;
+		}
+	}
+
+	switch (mode)
+	{
+	case UNIX_SVC_MODE_EXIT:
+		break;
+
+	case UNIX_SVC_MODE_START:
+		UnixStartService(name);
+		break;
+
+	case UNIX_SVC_MODE_STOP:
+		UnixStopService(name);
+		break;
+
+	case UNIX_SVC_MODE_EXEC_SVC:
+		UnixExecService(name, start, stop);
+		break;
+
+	default:
+		UnixUsage(name);
+		break;
+	}
+
+	// Mayaquq の終了
+	FreeMayaqua();
+
+	return;
+}
+
+#endif	// UNIX
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Unix.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Unix.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Unix.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,219 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Unix.h
+// Unix.c のヘッダ
+
+#ifdef	OS_UNIX
+
+#ifndef	UNIX_H
+#define	UNIX_H
+
+// 定数
+#define	UNIX_THREAD_STACK_SIZE			(200 * 1000)	// スタックサイズ
+#define	UNIX_MAX_CHILD_PROCESSES		2000000			// 最大子プロセス数
+#define	UNIX_LINUX_MAX_THREADS			200000000		// 最大スレッド数
+#define	UNIX_MAX_LOCKS					65536			// 最大ロック数
+#define	UNIX_MAX_MEMORY					(2147483648UL)	// 最大メモリ容量
+#define	UNIX_MAX_FD						(655360)		// 最大 FD 数
+#define	MAXIMUM_WAIT_OBJECTS			64				// 最大 select 数
+
+#define	UNIX_SERVICE_STOP_TIMEOUT_1		(600 * 1000)	// サービス停止までのタイムアウト
+#define	UNIX_SERVICE_STOP_TIMEOUT_2		(900 * 1000)	// サービス停止までのタイムアウト (親プロセス)
+
+
+// サービス関係
+typedef void (SERVICE_FUNCTION)();
+
+#define	SVC_NAME					"SVC_%s_NAME"
+#define	SVC_TITLE					"SVC_%s_TITLE"
+
+#define	UNIX_SVC_ARG_START				"start"
+#define	UNIX_SVC_ARG_STOP				"stop"
+#define	UNIX_SVC_ARG_EXEC_SVC			"execsvc"
+#define	UNIX_ARG_EXIT					"exit"
+
+#define	UNIX_SVC_MODE_START				1
+#define	UNIX_SVC_MODE_STOP				2
+#define	UNIX_SVC_MODE_EXEC_SVC			3
+#define	UNIX_SVC_MODE_EXIT				4
+
+
+// 関数プロトタイプ
+OS_DISPATCH_TABLE *UnixGetDispatchTable();
+void UnixInit();
+void UnixFree();
+void *UnixMemoryAlloc(UINT size);
+void *UnixMemoryReAlloc(void *addr, UINT size);
+void UnixMemoryFree(void *addr);
+UINT UnixGetTick();
+void UnixGetSystemTime(SYSTEMTIME *system_time);
+void UnixInc32(UINT *value);
+void UnixDec32(UINT *value);
+void UnixSleep(UINT time);
+LOCK *UnixNewLock();
+bool UnixLock(LOCK *lock);
+void UnixUnlock(LOCK *lock);
+void UnixUnlockEx(LOCK *lock, bool inner);
+void UnixDeleteLock(LOCK *lock);
+void UnixInitEvent(EVENT *event);
+void UnixSetEvent(EVENT *event);
+void UnixResetEvent(EVENT *event);
+bool UnixWaitEvent(EVENT *event, UINT timeout);
+void UnixFreeEvent(EVENT *event);
+bool UnixWaitThread(THREAD *t);
+void UnixFreeThread(THREAD *t);
+bool UnixInitThread(THREAD *t);
+UINT UnixThreadId();
+void *UnixFileOpen(char *name, bool write_mode, bool read_lock);
+void *UnixFileOpenW(wchar_t *name, bool write_mode, bool read_lock);
+void *UnixFileCreate(char *name);
+void *UnixFileCreateW(wchar_t *name);
+bool UnixFileWrite(void *pData, void *buf, UINT size);
+bool UnixFileRead(void *pData, void *buf, UINT size);
+void UnixFileClose(void *pData, bool no_flush);
+void UnixFileFlush(void *pData);
+UINT64 UnixFileSize(void *pData);
+bool UnixFileSeek(void *pData, UINT mode, int offset);
+bool UnixFileDelete(char *name);
+bool UnixFileDeleteW(wchar_t *name);
+bool UnixMakeDir(char *name);
+bool UnixMakeDirW(wchar_t *name);
+bool UnixDeleteDir(char *name);
+bool UnixDeleteDirW(wchar_t *name);
+CALLSTACK_DATA *UnixGetCallStack();
+bool UnixGetCallStackSymbolInfo(CALLSTACK_DATA *s);
+bool UnixFileRename(char *old_name, char *new_name);
+bool UnixFileRenameW(wchar_t *old_name, wchar_t *new_name);
+bool UnixRun(char *filename, char *arg, bool hide, bool wait);
+bool UnixRunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait);
+bool UnixIsSupportedOs();
+void UnixGetOsInfo(OS_INFO *info);
+void UnixAlert(char *msg, char *caption);
+void UnixAlertW(wchar_t *msg, wchar_t *caption);
+char *UnixGetProductId();
+void UnixSetHighPriority();
+void UnixRestorePriority();
+void *UnixNewSingleInstance(char *instance_name);
+void UnixFreeSingleInstance(void *data);
+void UnixGetMemInfo(MEMINFO *info);
+void UnixYield();
+
+
+void UnixSetThreadPriorityRealtime();
+void UnixSetThreadPriorityLow();
+void UnixSetThreadPriorityHigh();
+void UnixSetThreadPriorityIdle();
+void UnixRestoreThreadPriority();
+void UnixSetResourceLimit(UINT id, UINT value);
+UINT64 UnixGetTick64();
+void UnixSigChldHandler(int sig);
+void UnixCloseIO();
+void UnixDaemon(bool debug_mode);
+void UnixGetCurrentDir(char *dir, UINT size);
+void UnixGetCurrentDirW(wchar_t *dir, UINT size);
+bool UnixCheckExecAccess(char *name);
+bool UnixCheckExecAccessW(wchar_t *name);
+DIRLIST *UnixEnumDirEx(char *dirname, COMPARE *compare);
+DIRLIST *UnixEnumDirExW(wchar_t *dirname, COMPARE *compare);
+bool UnixGetDiskFreeMain(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size);
+bool UnixGetDiskFree(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size);
+bool UnixGetDiskFreeW(wchar_t *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size);
+void UnixInitSolarisSleep();
+void UnixFreeSolarisSleep();
+void UnixSolarisSleep(UINT msec);
+
+UINT UnixService(int argc, char *argv[], char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop);
+void UnixServiceMain(int argc, char *argv[], char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop);
+void UnixGenPidFileName(char *name, UINT size);
+void UnixStartService(char *name);
+void UnixStopService(char *name);
+void UnixExecService(char *name, SERVICE_FUNCTION *start, SERVICE_FUNCTION *stop);
+void UnixUsage(char *name);
+void UnixWritePidFile(UINT pid);
+UINT UnixReadPidFile();
+bool UnixIsProcess(UINT pid);
+bool UnixWaitProcessEx(UINT pid, UINT timeout);
+void UnixWaitProcess(UINT pid);
+void UnixDeletePidFile();
+void UnixStopThread(THREAD *t, void *param);
+
+
+#endif	// UNIX_H
+
+#endif	// OS_UNIX
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Win32.c
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Win32.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Win32.c	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,3165 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Win32.c
+// Microsoft Windows 依存コード
+
+#ifdef	WIN32
+
+#define	_WIN32_WINNT		0x0502
+#define	WINVER				0x0502
+#include <winsock2.h>
+#include <windows.h>
+#include <Dbghelp.h>
+#include <commctrl.h>
+#include <process.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include <stdarg.h>
+#include <time.h>
+#include <errno.h>
+#include <Mayaqua/Mayaqua.h>
+
+static HANDLE heap_handle = NULL;
+static HANDLE hstdout = INVALID_HANDLE_VALUE;
+static HANDLE hstdin = INVALID_HANDLE_VALUE;
+
+// Win32 用スレッドデータ
+typedef struct WIN32THREAD
+{
+	HANDLE hThread;
+	DWORD thread_id;
+} WIN32THREAD;
+
+// Win32 用スレッド起動情報
+typedef struct WIN32THREADSTARTUPINFO
+{
+	THREAD_PROC *thread_proc;
+	void *param;
+	THREAD *thread;
+} WIN32THREADSTARTUPINFO;
+
+// Win32 用関数プロトタイプ
+DWORD CALLBACK Win32DefaultThreadProc(void *param);
+
+// 現在のプロセスハンドル
+static HANDLE hCurrentProcessHandle = NULL;
+static CRITICAL_SECTION fasttick_lock;
+static UINT64 start_tick = 0;
+static bool use_heap_api = false;
+static bool win32_is_nt = false;
+
+// Win32 用ファイル I/O データ
+typedef struct WIN32IO
+{
+	HANDLE hFile;
+	bool WriteMode;
+} WIN32IO;
+
+// Win32 用ミューテックスデータ
+typedef struct WIN32MUTEX
+{
+	HANDLE hMutex;
+} WIN32MUTEX;
+
+// ディスパッチテーブルの作成
+OS_DISPATCH_TABLE *Win32GetDispatchTable()
+{
+	static OS_DISPATCH_TABLE t =
+	{
+		Win32Init,
+		Win32Free,
+		Win32MemoryAlloc,
+		Win32MemoryReAlloc,
+		Win32MemoryFree,
+		Win32GetTick,
+		Win32GetSystemTime,
+		Win32Inc32,
+		Win32Dec32,
+		Win32Sleep,
+		Win32NewLock,
+		Win32Lock,
+		Win32Unlock,
+		Win32DeleteLock,
+		Win32InitEvent,
+		Win32SetEvent,
+		Win32ResetEvent,
+		Win32WaitEvent,
+		Win32FreeEvent,
+		Win32WaitThread,
+		Win32FreeThread,
+		Win32InitThread,
+		Win32ThreadId,
+		Win32FileOpen,
+		Win32FileOpenW,
+		Win32FileCreate,
+		Win32FileCreateW,
+		Win32FileWrite,
+		Win32FileRead,
+		Win32FileClose,
+		Win32FileFlush,
+		Win32FileSize,
+		Win32FileSeek,
+		Win32FileDelete,
+		Win32FileDeleteW,
+		Win32MakeDir,
+		Win32MakeDirW,
+		Win32DeleteDir,
+		Win32DeleteDirW,
+		Win32GetCallStack,
+		Win32GetCallStackSymbolInfo,
+		Win32FileRename,
+		Win32FileRenameW,
+		Win32Run,
+		Win32RunW,
+		Win32IsSupportedOs,
+		Win32GetOsInfo,
+		Win32Alert,
+		Win32AlertW,
+		Win32GetProductId,
+		Win32SetHighPriority,
+		Win32RestorePriority,
+		Win32NewSingleInstance,
+		Win32FreeSingleInstance,
+		Win32GetMemInfo,
+		Win32Yield,
+	};
+
+	return &t;
+}
+
+// 新しいスレッド用の初期化関数
+void Win32InitNewThread()
+{
+	static HINSTANCE hDll = NULL;
+	static bool (WINAPI *_SetThreadLocale)(LCID) = NULL;
+
+	if (hDll == NULL)
+	{
+		hDll = LoadLibrary("kernel32.dll");
+
+		_SetThreadLocale =
+			(bool (__stdcall *)(LCID))
+			GetProcAddress(hDll, "SetThreadLocale");
+	}
+
+	if (_SetThreadLocale != NULL)
+	{
+		_SetThreadLocale(LOCALE_USER_DEFAULT);
+	}
+}
+
+// フォルダの圧縮フラグを設定する
+bool Win32SetFolderCompressW(wchar_t *path, bool compressed)
+{
+	HANDLE h;
+	UINT retsize = 0;
+	USHORT flag;
+	wchar_t tmp[MAX_PATH];
+	// 引数チェック
+	if (path == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char *path_a = CopyUniToStr(path);
+		bool ret = Win32SetFolderCompress(path_a, compressed);
+
+		Free(path_a);
+
+		return ret;
+	}
+
+	InnerFilePathW(tmp, sizeof(tmp), path);
+
+	// フォルダを開く
+	h = CreateFileW(tmp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		return false;
+	}
+
+	flag = compressed ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;
+
+	if (DeviceIoControl(h, FSCTL_SET_COMPRESSION, &flag, sizeof(USHORT),
+		NULL, 0, &retsize, NULL) == false)
+	{
+		return false;
+	}
+
+	CloseHandle(h);
+
+	return true;
+}
+bool Win32SetFolderCompress(char *path, bool compressed)
+{
+	HANDLE h;
+	UINT retsize = 0;
+	USHORT flag;
+	char tmp[MAX_PATH];
+	// 引数チェック
+	if (path == NULL)
+	{
+		return false;
+	}
+
+	InnerFilePath(tmp, sizeof(tmp), path);
+
+	// フォルダを開く
+	h = CreateFile(tmp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		return false;
+	}
+
+	flag = compressed ? COMPRESSION_FORMAT_DEFAULT : COMPRESSION_FORMAT_NONE;
+
+	if (DeviceIoControl(h, FSCTL_SET_COMPRESSION, &flag, sizeof(USHORT),
+		NULL, 0, &retsize, NULL) == false)
+	{
+		return false;
+	}
+
+	CloseHandle(h);
+
+	return true;
+}
+
+// ディスクの空き容量を取得する
+bool Win32GetDiskFreeW(wchar_t *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)
+{
+	wchar_t tmp[MAX_SIZE];
+	UINT count = 0;
+	UINT i, n, len;
+	ULARGE_INTEGER v1, v2, v3;
+	bool ret = false;
+	// 引数チェック
+	if (path == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		bool ret;
+		char *path_a = CopyUniToStr(path);
+
+		ret = Win32GetDiskFree(path_a, free_size, used_size, total_size);
+
+		Free(path_a);
+
+		return ret;
+	}
+
+	Zero(&v1, sizeof(v1));
+	Zero(&v2, sizeof(v2));
+	Zero(&v3, sizeof(v3));
+
+	NormalizePathW(tmp, sizeof(tmp), path);
+
+	// ディレクトリ名を取得
+	if (UniStartWith(path, L"\\\\"))
+	{
+		count = 4;
+	}
+	else
+	{
+		count = 1;
+	}
+
+	len = UniStrLen(tmp);
+	n = 0;
+	for (i = 0;i < len;i++)
+	{
+		if (tmp[i] == L'\\')
+		{
+			n++;
+			if (n >= count)
+			{
+				tmp[i + 1] = 0;
+				break;
+			}
+		}
+	}
+
+	if (GetDiskFreeSpaceExW(tmp, &v1, &v2, &v3))
+	{
+		ret = true;
+	}
+
+	if (free_size != NULL)
+	{
+		*free_size = v1.QuadPart;
+	}
+
+	if (total_size != NULL)
+	{
+		*total_size = v2.QuadPart;
+	}
+
+	if (used_size != NULL)
+	{
+		*used_size = v2.QuadPart - v1.QuadPart;
+	}
+
+	return ret;
+}
+bool Win32GetDiskFree(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size)
+{
+	char tmp[MAX_SIZE];
+	UINT count = 0;
+	UINT i, n, len;
+	ULARGE_INTEGER v1, v2, v3;
+	bool ret = false;
+	// 引数チェック
+	if (path == NULL)
+	{
+		return false;
+	}
+
+	Zero(&v1, sizeof(v1));
+	Zero(&v2, sizeof(v2));
+	Zero(&v3, sizeof(v3));
+
+	NormalizePath(tmp, sizeof(tmp), path);
+
+	// ディレクトリ名を取得
+	if (StartWith(path, "\\\\"))
+	{
+		count = 4;
+	}
+	else
+	{
+		count = 1;
+	}
+
+	len = StrLen(tmp);
+	n = 0;
+	for (i = 0;i < len;i++)
+	{
+		if (tmp[i] == '\\')
+		{
+			n++;
+			if (n >= count)
+			{
+				tmp[i + 1] = 0;
+				break;
+			}
+		}
+	}
+
+	if (GetDiskFreeSpaceEx(tmp, &v1, &v2, &v3))
+	{
+		ret = true;
+	}
+
+	if (free_size != NULL)
+	{
+		*free_size = v1.QuadPart;
+	}
+
+	if (total_size != NULL)
+	{
+		*total_size = v2.QuadPart;
+	}
+
+	if (used_size != NULL)
+	{
+		*used_size = v2.QuadPart - v1.QuadPart;
+	}
+
+	return ret;
+}
+
+// ディレクトリの列挙
+DIRLIST *Win32EnumDirEx(char *dirname, COMPARE *compare)
+{
+	DIRLIST *ret;
+	wchar_t *dirname_w = CopyStrToUni(dirname);
+
+	ret = Win32EnumDirExW(dirname_w, compare);
+
+	Free(dirname_w);
+
+	return ret;
+}
+DIRLIST *Win32EnumDirExW(wchar_t *dirname, COMPARE *compare)
+{
+	WIN32_FIND_DATAA data_a;
+	WIN32_FIND_DATAW data_w;
+	HANDLE h;
+	wchar_t tmp[MAX_PATH];
+	wchar_t tmp2[MAX_PATH];
+	wchar_t dirname2[MAX_PATH];
+	LIST *o;
+	DIRLIST *d;
+
+	UniStrCpy(tmp2, sizeof(tmp2), dirname);
+
+	if (UniStrLen(tmp2) >= 1 && tmp[UniStrLen(tmp2) - 1] == L'\\')
+	{
+		tmp2[UniStrLen(tmp2) - 1] = 0;
+	}
+
+	UniFormat(tmp, sizeof(tmp), L"%s\\*.*", tmp2);
+	NormalizePathW(tmp, sizeof(tmp), tmp);
+	NormalizePathW(dirname2, sizeof(dirname2), tmp2);
+
+	o = NewListFast(compare);
+
+	Zero(&data_a, sizeof(data_a));
+	Zero(&data_w, sizeof(data_w));
+
+	if (IsNt())
+	{
+		h = FindFirstFileW(tmp, &data_w);
+	}
+	else
+	{
+		char *tmp_a = CopyUniToStr(tmp);
+
+		h = FindFirstFileA(tmp_a, &data_a);
+
+		Free(tmp_a);
+	}
+
+	if (h != INVALID_HANDLE_VALUE)
+	{
+		bool b = true;
+
+		do
+		{
+			if (IsNt() == false)
+			{
+				Zero(&data_w, sizeof(data_w));
+				StrToUni(data_w.cFileName, sizeof(data_w.cFileName), data_a.cFileName);
+				data_w.dwFileAttributes = data_a.dwFileAttributes;
+				data_w.ftCreationTime = data_a.ftCreationTime;
+				data_w.ftLastWriteTime = data_a.ftLastWriteTime;
+				data_w.nFileSizeHigh = data_a.nFileSizeHigh;
+				data_w.nFileSizeLow = data_a.nFileSizeLow;
+			}
+
+			if (UniStrCmpi(data_w.cFileName, L"..") != 0 &&
+				UniStrCmpi(data_w.cFileName, L".") != 0)
+			{
+				DIRENT *f = ZeroMalloc(sizeof(DIRENT));
+				SYSTEMTIME t1, t2;
+				wchar_t fullpath[MAX_SIZE];
+				bool ok = false;
+
+				f->FileNameW = UniCopyStr(data_w.cFileName);
+				f->FileName = CopyUniToStr(f->FileNameW);
+				f->Folder = (data_w.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? true : false;
+
+				CombinePathW(fullpath, sizeof(fullpath), dirname2, f->FileNameW);
+
+				// ファイル情報の取得を試行する
+				if (MsIsNt())
+				{
+					HANDLE h = CreateFileW(fullpath, 0,
+						FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+						NULL, OPEN_EXISTING, 0, NULL);
+
+					if (h != INVALID_HANDLE_VALUE)
+					{
+						BY_HANDLE_FILE_INFORMATION info;
+
+						Zero(&info, sizeof(info));
+
+						if (MsGetFileInformation(h, &info))
+						{
+							Zero(&t1, sizeof(t1));
+							Zero(&t2, sizeof(t2));
+							FileTimeToSystemTime(&info.ftCreationTime, &t1);
+							FileTimeToSystemTime(&info.ftLastWriteTime, &t2);
+							f->CreateDate = SystemToUINT64(&t1);
+							f->UpdateDate = SystemToUINT64(&t2);
+
+							if (f->Folder == false)
+							{
+								f->FileSize = ((UINT64)info.nFileSizeHigh * (UINT64)((UINT64)MAXDWORD + (UINT64)1)) + (UINT64)info.nFileSizeLow;
+							}
+
+							ok = true;
+						}
+
+						CloseHandle(h);
+					}
+				}
+
+				if (ok == false)
+				{
+					Zero(&t1, sizeof(t1));
+					Zero(&t2, sizeof(t2));
+					FileTimeToSystemTime(&data_w.ftCreationTime, &t1);
+					FileTimeToSystemTime(&data_w.ftLastWriteTime, &t2);
+					f->CreateDate = SystemToUINT64(&t1);
+					f->UpdateDate = SystemToUINT64(&t2);
+
+					if (f->Folder == false)
+					{
+						f->FileSize = ((UINT64)data_w.nFileSizeHigh * (UINT64)((UINT64)MAXDWORD + (UINT64)1)) + (UINT64)data_w.nFileSizeLow;
+					}
+				}
+
+				Add(o, f);
+			}
+
+			Zero(&data_w, sizeof(data_w));
+			Zero(&data_a, sizeof(data_a));
+
+			if (IsNt())
+			{
+				b = FindNextFileW(h, &data_w);
+			}
+			else
+			{
+				b = FindNextFileA(h, &data_a);
+			}
+		}
+		while (b);
+
+		FindClose(h);
+	}
+
+	Sort(o);
+
+	d = ZeroMalloc(sizeof(DIRLIST));
+	d->NumFiles = LIST_NUM(o);
+	d->File = ToArray(o);
+
+	ReleaseList(o);
+
+	return d;
+}
+
+// EXE ファイル名を取得
+void Win32GetExeNameW(wchar_t *name, UINT size)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	if (IsNt() == false)
+	{
+		char name_a[MAX_PATH];
+
+		Win32GetExeName(name_a, sizeof(name_a));
+
+		StrToUni(name, size, name_a);
+
+		return;
+	}
+
+	UniStrCpy(name, size, L"");
+
+	GetModuleFileNameW(NULL, name, size);
+}
+void Win32GetExeName(char *name, UINT size)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	StrCpy(name, size, "");
+
+	GetModuleFileName(NULL, name, size);
+}
+
+// 現在のディレクトリの取得
+void Win32GetCurrentDirW(wchar_t *dir, UINT size)
+{
+	// 引数チェック
+	if (dir == NULL)
+	{
+		return;
+	}
+
+	if (IsNt() == false)
+	{
+		char dir_a[MAX_PATH];
+
+		Win32GetCurrentDir(dir_a, sizeof(dir_a));
+
+		StrToUni(dir, size, dir_a);
+
+		return;
+	}
+
+	GetCurrentDirectoryW(size, dir);
+}
+void Win32GetCurrentDir(char *dir, UINT size)
+{
+	// 引数チェック
+	if (dir == NULL)
+	{
+		return;
+	}
+
+	GetCurrentDirectory(size, dir);
+}
+
+// イールド
+void Win32Yield()
+{
+	Sleep(0);
+}
+
+// メモリ情報の取得
+void Win32GetMemInfo(MEMINFO *info)
+{
+	MEMORYSTATUS st;
+	// 引数チェック
+	if (info == NULL)
+	{
+		return;
+	}
+
+	Zero(info, sizeof(MEMINFO));
+	Zero(&st, sizeof(st));
+	st.dwLength = sizeof(st);
+
+	GlobalMemoryStatus(&st);
+
+	// 論理メモリ量
+	info->TotalMemory = (UINT64)st.dwTotalPageFile;
+	info->FreeMemory = (UINT64)st.dwAvailPageFile;
+	info->UsedMemory = info->TotalMemory - info->FreeMemory;
+
+	// 物理メモリ量
+	info->TotalPhys = (UINT64)st.dwTotalPhys;
+	info->FreePhys = (UINT64)st.dwAvailPhys;
+	info->UsedPhys = info->TotalPhys - info->FreePhys;
+}
+
+// シングルインスタンスの作成
+void *Win32NewSingleInstance(char *instance_name)
+{
+	WIN32MUTEX *ret;
+	char tmp[MAX_SIZE];
+	HANDLE hMutex;
+	// 引数チェック
+	if (instance_name == NULL)
+	{
+		char exe_path[MAX_PATH];
+		GetModuleFileName(NULL, exe_path, sizeof(exe_path));
+		HashInstanceName(tmp, sizeof(tmp), exe_path);
+		instance_name = tmp;
+	}
+
+	hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, instance_name);
+	if (hMutex != NULL)
+	{
+		CloseHandle(hMutex);
+		return NULL;
+	}
+
+	hMutex = CreateMutex(NULL, FALSE, instance_name);
+	if (hMutex == NULL)
+	{
+		CloseHandle(hMutex);
+		return NULL;
+	}
+
+	ret = Win32MemoryAlloc(sizeof(WIN32MUTEX));
+	ret->hMutex = hMutex;
+
+	return (void *)ret;
+}
+
+// シングルインスタンスの解放
+void Win32FreeSingleInstance(void *data)
+{
+	WIN32MUTEX *m;
+	// 引数チェック
+	if (data == NULL)
+	{
+		return;
+	}
+
+	m = (WIN32MUTEX *)data;
+	ReleaseMutex(m->hMutex);
+	CloseHandle(m->hMutex);
+
+	Win32MemoryFree(m);
+}
+
+// 優先順位を高くする
+void Win32SetHighPriority()
+{
+	SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
+}
+
+// 優先順位を戻す
+void Win32RestorePriority()
+{
+	SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
+}
+
+// ノード情報を取得
+char* Win32GetProductId()
+{
+	char *product_id;
+
+	return CopyStr("--");
+
+	// プロダクト ID
+	product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductId");
+	if (product_id == NULL)
+	{
+		product_id = MsRegReadStr(REG_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion", "ProductId");
+	}
+
+	return product_id;
+}
+
+// 現在サポートされている OS かどうか取得
+bool Win32IsSupportedOs()
+{
+	if (Win32GetOsType() == 0)
+	{
+		Win32Alert(
+			"SoftEther UT-VPN doesn't support this Windows Operating System.\n"
+			"SoftEther UT-VPN requires " SUPPORTED_WINDOWS_LIST ".\n\n"
+			"Please contact your system administrator.", NULL);
+		return false;
+	}
+
+	return true;
+}
+
+// アラートの表示
+void Win32AlertW(wchar_t *msg, wchar_t *caption)
+{
+	char *s;
+	// 引数チェック
+	if (msg == NULL)
+	{
+		msg = L"Alert";
+	}
+	if (caption == NULL)
+	{
+		caption = L"SoftEther UT-VPN Kernel";
+	}
+
+	s = GetCommandLineStr();
+
+	if (SearchStr(s, "win9x_uninstall", 0) == INFINITE && SearchStr(s, "win9x_install", 0) == INFINITE)
+	{
+		// Win9x サービスモードのアンインストール時には非表示とする
+		MessageBoxW(NULL, msg, caption, MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);
+	}
+
+	Free(s);
+}
+void Win32Alert(char *msg, char *caption)
+{
+	char *s;
+	// 引数チェック
+	if (msg == NULL)
+	{
+		msg = "Alert";
+	}
+	if (caption == NULL)
+	{
+		caption = "SoftEther UT-VPN Kernel";
+	}
+
+	s = GetCommandLineStr();
+
+	if (SearchStr(s, "win9x_uninstall", 0) == INFINITE && SearchStr(s, "win9x_install", 0) == INFINITE)
+	{
+		// Win9x サービスモードのアンインストール時には非表示とする
+		MessageBox(NULL, msg, caption, MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);
+	}
+
+	Free(s);
+}
+void Win32DebugAlert(char *msg)
+{
+	// 引数チェック
+	if (msg == NULL)
+	{
+		msg = "Alert";
+	}
+
+	MessageBox(NULL, msg, "Debug", MB_SETFOREGROUND | MB_TOPMOST | MB_SERVICE_NOTIFICATION | MB_OK | MB_ICONEXCLAMATION);
+}
+
+// OS 情報の取得
+void Win32GetOsInfo(OS_INFO *info)
+{
+	UINT type = Win32GetOsType();
+	OSVERSIONINFOEX os;
+	char tmp[MAX_SIZE];
+	// 引数チェック
+	if (info == NULL)
+	{
+		return;
+	}
+
+	Zero(&os, sizeof(os));
+	os.dwOSVersionInfoSize = sizeof(os);
+	GetVersionEx((LPOSVERSIONINFOA)&os);
+
+	info->OsType = Win32GetOsType();
+	info->OsServicePack = os.wServicePackMajor;
+	if (OS_IS_WINDOWS_NT(info->OsType))
+	{
+		char *s;
+		char *keyname = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
+		info->OsSystemName = CopyStr("Windows NT");
+		Format(tmp, sizeof(tmp), "Build %u", os.dwBuildNumber);
+		if (s = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "CurrentType"))
+		{
+			char str[MAX_SIZE];
+			Format(str, sizeof(str), ", %s", s);
+			StrCat(tmp, sizeof(tmp), str);
+			Free(s);
+		}
+		if (os.wServicePackMajor != 0)
+		{
+			char str[MAX_SIZE];
+			Format(str, sizeof(str), ", Service Pack %u", os.wServicePackMajor);
+			StrCat(tmp, sizeof(tmp), str);
+		}
+		if (s = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "BuildLab"))
+		{
+			char str[MAX_SIZE];
+			Format(str, sizeof(str), " (%s)", s);
+			StrCat(tmp, sizeof(tmp), str);
+			Free(s);
+		}
+		info->OsVersion = CopyStr(tmp);
+		info->KernelName = CopyStr("NTOS Kernel");
+		Format(tmp, sizeof(tmp), "Build %u", os.dwBuildNumber);
+		if (s = MsRegReadStr(REG_LOCAL_MACHINE, keyname, "CurrentType"))
+		{
+			char str[MAX_SIZE];
+			Format(str, sizeof(str), " %s", s);
+			StrCat(tmp, sizeof(tmp), str);
+			Free(s);
+		}
+		info->KernelVersion = CopyStr(tmp);
+	}
+	else
+	{
+		OSVERSIONINFO os;
+		Zero(&os, sizeof(os));
+		os.dwOSVersionInfoSize = sizeof(os);
+		GetVersionEx(&os);
+		Format(tmp, sizeof(tmp), "Build %u %s", LOWORD(os.dwBuildNumber), os.szCSDVersion);
+		Trim(tmp);
+		info->OsVersion = CopyStr(tmp);
+		info->OsSystemName = CopyStr("Windows");
+		info->KernelName = CopyStr("Windows 9x Kernel");
+		info->KernelVersion = CopyStr(tmp);
+	}
+
+	info->OsProductName = CopyStr(OsTypeToStr(info->OsType));
+	info->OsVendorName = CopyStr("Microsoft Corporation");
+}
+
+// Windows NT かどうか取得
+bool Win32IsNt()
+{
+	OSVERSIONINFO os;
+	Zero(&os, sizeof(os));
+	os.dwOSVersionInfoSize = sizeof(os);
+
+	if (GetVersionEx(&os) == FALSE)
+	{
+		// 失敗?
+		return false;
+	}
+
+	if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
+	{
+		// NT
+		return true;
+	}
+
+	// 9x
+	return false;
+}
+
+// OS 種類の取得
+UINT Win32GetOsType()
+{
+	OSVERSIONINFO os;
+	Zero(&os, sizeof(os));
+	os.dwOSVersionInfoSize = sizeof(os);
+
+	if (GetVersionEx(&os) == FALSE)
+	{
+		// 失敗?
+		return 0;
+	}
+
+	if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+	{
+		// Windows 9x 系
+		if (os.dwMajorVersion == 4)
+		{
+			if (os.dwMinorVersion == 0)
+			{
+				return OSTYPE_WINDOWS_95;
+			}
+			else if (os.dwMinorVersion == 10)
+			{
+				return OSTYPE_WINDOWS_98;
+			}
+			else if (os.dwMinorVersion == 90)
+			{
+				return OSTYPE_WINDOWS_ME;
+			}
+			else
+			{
+				return OSTYPE_WINDOWS_UNKNOWN;
+			}
+		}
+		else if (os.dwMajorVersion >= 5)
+		{
+			return OSTYPE_WINDOWS_UNKNOWN;
+		}
+	}
+	else if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
+	{
+		UINT sp = Win32GetSpVer(os.szCSDVersion);
+		if (os.dwMajorVersion == 4)
+		{
+			if (sp < 6)
+			{
+				// SP6 以前
+				return 0;
+			}
+		}
+		if (os.dwMajorVersion < 4)
+		{
+			// NT 3.51 以前
+			return 0;
+		}
+		else
+		{
+			OSVERSIONINFOEX os;
+			Zero(&os, sizeof(os));
+			os.dwOSVersionInfoSize = sizeof(os);
+			GetVersionEx((LPOSVERSIONINFOA)&os);
+
+			if (os.dwMajorVersion == 4)
+			{
+				// Windows NT 4.0
+				if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
+				{
+					if ((os.wSuiteMask & VER_SUITE_TERMINAL) || (os.wSuiteMask & VER_SUITE_SINGLEUSERTS))
+					{
+						return OSTYPE_WINDOWS_NT_4_TERMINAL_SERVER;
+					}
+					if (os.wSuiteMask & VER_SUITE_ENTERPRISE)
+					{
+						return OSTYPE_WINDOWS_NT_4_SERVER_ENTERPRISE;
+					}
+					if (os.wSuiteMask & VER_SUITE_BACKOFFICE)
+					{
+						return OSTYPE_WINDOWS_NT_4_BACKOFFICE;
+					}
+					if ((os.wSuiteMask & VER_SUITE_SMALLBUSINESS) || (os.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))
+					{
+						return OSTYPE_WINDOWS_NT_4_SMS;
+					}
+					else
+					{
+						return OSTYPE_WINDOWS_NT_4_SERVER;
+					}
+				}
+				else
+				{
+					return OSTYPE_WINDOWS_NT_4_WORKSTATION;
+				}
+			}
+			else if (os.dwMajorVersion == 5)
+			{
+				// Windows 2000, XP, Server 2003
+				if (os.dwMinorVersion == 0)
+				{
+					// Windows 2000
+					if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
+					{
+						// Server
+						if (os.wSuiteMask & VER_SUITE_DATACENTER)
+						{
+							return OSTYPE_WINDOWS_2000_DATACENTER_SERVER;
+						}
+						else if ((os.wSuiteMask & VER_SUITE_SMALLBUSINESS) || (os.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))
+						{
+							return OSTYPE_WINDOWS_2000_SBS;
+						}
+						else if (os.wSuiteMask & VER_SUITE_BACKOFFICE)
+						{
+							return OSTYPE_WINDOWS_2000_BACKOFFICE;
+						}
+						else if (os.wSuiteMask & VER_SUITE_ENTERPRISE)
+						{
+							return OSTYPE_WINDOWS_2000_ADVANCED_SERVER;
+						}
+						else
+						{
+							return OSTYPE_WINDOWS_2000_SERVER;
+						}
+					}
+					else
+					{
+						// Client
+						return OSTYPE_WINDOWS_2000_PROFESSIONAL;
+					}
+				}
+				else if (os.dwMinorVersion == 1)
+				{
+					// Windows XP
+					if (os.wSuiteMask & VER_SUITE_PERSONAL)
+					{
+						return OSTYPE_WINDOWS_XP_HOME;
+					}
+					else
+					{
+						return OSTYPE_WINDOWS_XP_PROFESSIONAL;
+					}
+				}
+				else if (os.dwMinorVersion == 2)
+				{
+					// Windows Server 2003
+					if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
+					{
+						// Server
+						if (os.wSuiteMask & VER_SUITE_DATACENTER)
+						{
+							return OSTYPE_WINDOWS_2003_DATACENTER;
+						}
+						else if ((os.wSuiteMask & VER_SUITE_SMALLBUSINESS) || (os.wSuiteMask & VER_SUITE_SMALLBUSINESS_RESTRICTED))
+						{
+							return OSTYPE_WINDOWS_2003_SBS;
+						}
+						else if (os.wSuiteMask & VER_SUITE_BACKOFFICE)
+						{
+							return OSTYPE_WINDOWS_2003_BACKOFFICE;
+						}
+						else if (os.wSuiteMask & VER_SUITE_ENTERPRISE)
+						{
+							return OSTYPE_WINDOWS_2003_ENTERPRISE;
+						}
+						else if (os.wSuiteMask & VER_SUITE_BLADE)
+						{
+							return OSTYPE_WINDOWS_2003_WEB;
+						}
+						else
+						{
+							return OSTYPE_WINDOWS_2003_STANDARD;
+						}
+					}
+					else
+					{
+						// Client (Unknown XP?)
+						return OSTYPE_WINDOWS_XP_PROFESSIONAL;
+					}
+				}
+				else
+				{
+					// Windows Longhorn
+					if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
+					{
+						return OSTYPE_WINDOWS_LONGHORN_SERVER;
+					}
+					else
+					{
+						return OSTYPE_WINDOWS_LONGHORN_PROFESSIONAL;
+					}
+				}
+			}
+			else
+			{
+				if (os.dwMajorVersion == 6 && os.dwMinorVersion == 0)
+				{
+					// Windows Vista, Server 2008
+					if (os.wProductType == VER_NT_DOMAIN_CONTROLLER || os.wProductType == VER_NT_SERVER)
+					{
+						return OSTYPE_WINDOWS_LONGHORN_SERVER;
+					}
+					else
+					{
+						return OSTYPE_WINDOWS_LONGHORN_PROFESSIONAL;
+					}
+				}
+				else if (os.dwMajorVersion == 6 && os.dwMinorVersion == 1)
+				{
+					if (os.wProductType == VER_NT_WORKSTATION)
+					{
+						// Windows 7
+						return OSTYPE_WINDOWS_7;
+					}
+					else
+					{
+						// Windows Server 2008 R2
+						return OSTYPE_WINDOWS_SERVER_2008_R2;
+					}
+				}
+				else
+				{
+					if (os.wProductType == VER_NT_WORKSTATION)
+					{
+						// Windows 8
+						return OSTYPE_WINDOWS_8;
+					}
+					else
+					{
+						// Windows Server 8
+						return OSTYPE_WINDOWS_SERVER_2008_R2;
+					}
+				}
+			}
+		}
+	}
+
+	// 判別できない
+	return 0;
+}
+
+// 文字列から SP のバージョンを取得する
+UINT Win32GetSpVer(char *str)
+{
+	UINT ret, i;
+	TOKEN_LIST *t;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return 0;
+	}
+
+	t = ParseToken(str, NULL);
+	if (t == NULL)
+	{
+		return 0;
+	}
+
+	ret = 0;
+	for (i = 0;i < t->NumTokens;i++)
+	{
+		ret = ToInt(t->Token[i]);
+		if (ret != 0)
+		{
+			break;
+		}
+	}
+
+	FreeToken(t);
+
+	return ret;
+}
+
+// プロセスの強制終了
+bool Win32TerminateProcess(void *handle)
+{
+	HANDLE h;
+	// 引数チェック
+	if (handle == NULL)
+	{
+		return false;
+	}
+
+	h = (HANDLE)handle;
+
+	TerminateProcess(h, 0);
+
+	return true;
+}
+
+// プロセスを閉じる
+void Win32CloseProcess(void *handle)
+{
+	// 引数チェック
+	if (handle == NULL)
+	{
+		return;
+	}
+
+	CloseHandle((HANDLE)handle);
+}
+
+// 指定されたプロセスが生きているかどうかチェック
+bool Win32IsProcessAlive(void *handle)
+{
+	HANDLE h;
+	// 引数チェック
+	if (handle == NULL)
+	{
+		return false;
+	}
+
+	h = (HANDLE)handle;
+
+	if (WaitForSingleObject(h, 0) == WAIT_OBJECT_0)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// プロセスの終了を待機する
+bool Win32WaitProcess(void *h, UINT timeout)
+{
+	// 引数チェック
+	if (h == NULL)
+	{
+		return false;
+	}
+	if (timeout == 0)
+	{
+		timeout = INFINITE;
+	}
+
+	if (WaitForSingleObject((HANDLE)h, timeout) == WAIT_TIMEOUT)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// プロセスの起動 (ハンドルを返す)
+void *Win32RunExW(wchar_t *filename, wchar_t *arg, bool hide)
+{
+	return Win32RunEx2W(filename, arg, hide, NULL);
+}
+void *Win32RunEx2W(wchar_t *filename, wchar_t *arg, bool hide, UINT *process_id)
+{
+	return Win32RunEx3W(filename, arg, hide, process_id, false);
+}
+void *Win32RunEx3W(wchar_t *filename, wchar_t *arg, bool hide, UINT *process_id, bool disableWow)
+{
+	STARTUPINFOW info;
+	PROCESS_INFORMATION ret;
+	wchar_t cmdline[MAX_SIZE];
+	wchar_t name[MAX_PATH];
+	void *p;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return NULL;
+	}
+
+	if (IsNt() == false)
+	{
+		char *filename_a = CopyUniToStr(filename);
+		char *arg_a = CopyUniToStr(arg);
+		void *ret = Win32RunEx(filename_a, arg_a, hide);
+
+		Free(filename_a);
+		Free(arg_a);
+
+		return ret;
+	}
+
+	UniStrCpy(name, sizeof(name), filename);
+	UniTrim(name);
+
+	if (UniSearchStr(name, L"\"", 0) == INFINITE)
+	{
+		if (arg == NULL)
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"%s", name);
+		}
+		else
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"%s %s", name, arg);
+		}
+	}
+	else
+	{
+		if (arg == NULL)
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"\"%s\"", name);
+		}
+		else
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"\"%s\" %s", name, arg);
+		}
+	}
+
+	Zero(&info, sizeof(info));
+	Zero(&ret, sizeof(ret));
+	info.cb = sizeof(info);
+	info.dwFlags = STARTF_USESHOWWINDOW;
+	info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
+
+	UniTrim(cmdline);
+
+	if (disableWow)
+	{
+		p = MsDisableWow64FileSystemRedirection();
+	}
+
+	if (CreateProcessW(NULL, cmdline, NULL, NULL, FALSE,
+		(hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
+		NULL, NULL, &info, &ret) == FALSE)
+	{
+		if (disableWow)
+		{
+			MsRestoreWow64FileSystemRedirection(p);
+		}
+		return NULL;
+	}
+
+	if (disableWow)
+	{
+		MsRestoreWow64FileSystemRedirection(p);
+	}
+
+	if (process_id != NULL)
+	{
+		*process_id = ret.dwProcessId;
+	}
+
+	CloseHandle(ret.hThread);
+	return ret.hProcess;
+}
+void *Win32RunEx(char *filename, char *arg, bool hide)
+{
+	return Win32RunEx2(filename, arg, hide, NULL);
+}
+void *Win32RunEx2(char *filename, char *arg, bool hide, UINT *process_id)
+{
+	return Win32RunEx3(filename, arg, hide, process_id, false);
+}
+void *Win32RunEx3(char *filename, char *arg, bool hide, UINT *process_id, bool disableWow)
+{
+	STARTUPINFO info;
+	PROCESS_INFORMATION ret;
+	char cmdline[MAX_SIZE];
+	char name[MAX_PATH];
+	void *p = NULL;
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return NULL;
+	}
+
+	StrCpy(name, sizeof(name), filename);
+	Trim(name);
+
+	if (SearchStr(name, "\"", 0) == INFINITE)
+	{
+		if (arg == NULL)
+		{
+			Format(cmdline, sizeof(cmdline), "%s", name);
+		}
+		else
+		{
+			Format(cmdline, sizeof(cmdline), "%s %s", name, arg);
+		}
+	}
+	else
+	{
+		if (arg == NULL)
+		{
+			Format(cmdline, sizeof(cmdline), "\"%s\"", name);
+		}
+		else
+		{
+			Format(cmdline, sizeof(cmdline), "\"%s\" %s", name, arg);
+		}
+	}
+
+	Zero(&info, sizeof(info));
+	Zero(&ret, sizeof(ret));
+	info.cb = sizeof(info);
+	info.dwFlags = STARTF_USESHOWWINDOW;
+	info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
+
+	Trim(cmdline);
+
+	if (disableWow)
+	{
+		p = MsDisableWow64FileSystemRedirection();
+	}
+
+	if (CreateProcess(NULL, cmdline, NULL, NULL, FALSE,
+		(hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
+		NULL, NULL, &info, &ret) == FALSE)
+	{
+		if (disableWow)
+		{
+			MsRestoreWow64FileSystemRedirection(p);
+		}
+		return NULL;
+	}
+	if (disableWow)
+	{
+		MsRestoreWow64FileSystemRedirection(p);
+	}
+
+	if (process_id != NULL)
+	{
+		*process_id = ret.dwProcessId;
+	}
+
+	CloseHandle(ret.hThread);
+	return ret.hProcess;
+}
+
+// プロセスの起動
+bool Win32RunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait)
+{
+	STARTUPINFOW info;
+	PROCESS_INFORMATION ret;
+	wchar_t cmdline[MAX_SIZE];
+	wchar_t name[MAX_PATH];
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char *filename_a = CopyUniToStr(filename);
+		char *arg_a = CopyUniToStr(arg);
+		bool ret;
+
+		ret = Win32Run(filename_a, arg_a, hide, wait);
+
+		Free(filename_a);
+		Free(arg_a);
+
+		return ret;
+	}
+
+	UniStrCpy(name, sizeof(name), filename);
+	UniTrim(name);
+
+	if (UniSearchStr(name, L"\"", 0) == INFINITE)
+	{
+		if (arg == NULL)
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"%s", name);
+		}
+		else
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"%s %s", name, arg);
+		}
+	}
+	else
+	{
+		if (arg == NULL)
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"\"%s\"", name);
+		}
+		else
+		{
+			UniFormat(cmdline, sizeof(cmdline), L"\"%s\" %s", name, arg);
+		}
+	}
+
+	Zero(&info, sizeof(info));
+	Zero(&ret, sizeof(ret));
+	info.cb = sizeof(info);
+	info.dwFlags = STARTF_USESHOWWINDOW;
+	info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
+
+	UniTrim(cmdline);
+
+	if (CreateProcessW(NULL, cmdline, NULL, NULL, FALSE,
+		(hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
+		NULL, NULL, &info, &ret) == FALSE)
+	{
+		return false;
+	}
+
+	if (wait)
+	{
+		WaitForSingleObject(ret.hProcess, INFINITE);
+	}
+
+	CloseHandle(ret.hThread);
+	CloseHandle(ret.hProcess);
+
+	return true;
+}
+bool Win32Run(char *filename, char *arg, bool hide, bool wait)
+{
+	STARTUPINFO info;
+	PROCESS_INFORMATION ret;
+	char cmdline[MAX_SIZE];
+	char name[MAX_PATH];
+	// 引数チェック
+	if (filename == NULL)
+	{
+		return false;
+	}
+
+	StrCpy(name, sizeof(name), filename);
+	Trim(name);
+
+	if (SearchStr(name, "\"", 0) == INFINITE)
+	{
+		if (arg == NULL)
+		{
+			Format(cmdline, sizeof(cmdline), "%s", name);
+		}
+		else
+		{
+			Format(cmdline, sizeof(cmdline), "%s %s", name, arg);
+		}
+	}
+	else
+	{
+		if (arg == NULL)
+		{
+			Format(cmdline, sizeof(cmdline), "\"%s\"", name);
+		}
+		else
+		{
+			Format(cmdline, sizeof(cmdline), "\"%s\" %s", name, arg);
+		}
+	}
+
+	Zero(&info, sizeof(info));
+	Zero(&ret, sizeof(ret));
+	info.cb = sizeof(info);
+	info.dwFlags = STARTF_USESHOWWINDOW;
+	info.wShowWindow = (hide == false ? SW_SHOWDEFAULT : SW_HIDE);
+
+	Trim(cmdline);
+
+	if (CreateProcess(NULL, cmdline, NULL, NULL, FALSE,
+		(hide == false ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW | CREATE_NEW_CONSOLE) | NORMAL_PRIORITY_CLASS,
+		NULL, NULL, &info, &ret) == FALSE)
+	{
+		return false;
+	}
+
+	if (wait)
+	{
+		WaitForSingleObject(ret.hProcess, INFINITE);
+	}
+
+	CloseHandle(ret.hThread);
+	CloseHandle(ret.hProcess);
+
+	return true;
+}
+
+// スレッド ID の取得
+UINT Win32ThreadId()
+{
+	return GetCurrentThreadId();
+}
+
+// ファイル名の変更
+bool Win32FileRenameW(wchar_t *old_name, wchar_t *new_name)
+{
+	// 引数チェック
+	if (old_name == NULL || new_name == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char *old_name_a = CopyUniToStr(old_name);
+		char *new_name_a = CopyUniToStr(new_name);
+		bool ret = Win32FileRename(old_name_a, new_name_a);
+
+		Free(old_name_a);
+		Free(new_name_a);
+
+		return ret;
+	}
+
+	// リネーム
+	if (MoveFileW(old_name, new_name) == FALSE)
+	{
+		return false;
+	}
+
+	return true;
+}
+bool Win32FileRename(char *old_name, char *new_name)
+{
+	// 引数チェック
+	if (old_name == NULL || new_name == NULL)
+	{
+		return false;
+	}
+
+	// リネーム
+	if (MoveFile(old_name, new_name) == FALSE)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// EXE ファイルが存在しているディレクトリ名を取得する
+void Win32GetExeDirW(wchar_t *name, UINT size)
+{
+	wchar_t exe_path[MAX_SIZE];
+	wchar_t exe_dir[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	if (IsNt() == false)
+	{
+		char name_a[MAX_PATH];
+
+		Win32GetExeDir(name_a, sizeof(name_a));
+
+		StrToUni(name, size, name_a);
+
+		return;
+	}
+
+	// EXE ファイル名を取得
+	GetModuleFileNameW(NULL, exe_path, sizeof(exe_path));
+
+	// ディレクトリ名を取得
+	Win32GetDirFromPathW(exe_dir, sizeof(exe_dir), exe_path);
+
+	UniStrCpy(name, size, exe_dir);
+}
+void Win32GetExeDir(char *name, UINT size)
+{
+	char exe_path[MAX_SIZE];
+	char exe_dir[MAX_SIZE];
+	// 引数チェック
+	if (name == NULL)
+	{
+		return;
+	}
+
+	// EXE ファイル名を取得
+	GetModuleFileName(NULL, exe_path, sizeof(exe_path));
+
+	// ディレクトリ名を取得
+	Win32GetDirFromPath(exe_dir, sizeof(exe_dir), exe_path);
+
+	StrCpy(name, size, exe_dir);
+}
+
+// 終端の \ を抜く
+void Win32NukuEnW(wchar_t *dst, UINT size, wchar_t *src)
+{
+	wchar_t str[MAX_SIZE];
+	int i;
+	if (src)
+	{
+		UniStrCpy(str, sizeof(str), src);
+	}
+	else
+	{
+		UniStrCpy(str, sizeof(str), dst);
+	}
+	i = UniStrLen(str);
+	if (str[i - 1] == L'\\')
+	{
+		str[i - 1] = 0;
+	}
+	UniStrCpy(dst, size, str);
+}
+void Win32NukuEn(char *dst, UINT size, char *src)
+{
+	char str[MAX_SIZE];
+	int i;
+	if (src)
+	{
+		StrCpy(str, sizeof(str), src);
+	}
+	else
+	{
+		StrCpy(str, sizeof(str), dst);
+	}
+	i = StrLen(str);
+	if (str[i - 1] == '\\')
+	{
+		str[i - 1] = 0;
+	}
+	StrCpy(dst, size, str);
+}
+
+// ディレクトリ名をパスから取得
+void Win32GetDirFromPathW(wchar_t *dst, UINT size, wchar_t *src)
+{
+	wchar_t str[MAX_SIZE];
+	int i,len;
+	wchar_t c;
+	wchar_t tmp[MAX_SIZE];
+	int wp;
+	if (src)
+	{
+		UniStrCpy(str, sizeof(str), src);
+	}
+	else
+	{
+		UniStrCpy(str, sizeof(str), dst);
+	}
+	Win32NukuEnW(str, sizeof(str), NULL);
+	wp = 0;
+	len = UniStrLen(str);
+	dst[0] = 0;
+	for (i = 0;i < len;i++)
+	{
+		c = str[i];
+		switch (c)
+		{
+		case L'\\':
+			tmp[wp] = 0;
+			wp = 0;
+			UniStrCat(dst, size, tmp);
+			UniStrCat(dst, size, L"\\");
+			break;
+		default:
+			tmp[wp] = c;
+			wp++;
+			break;
+		}
+	}
+	Win32NukuEnW(dst, size, NULL);
+}
+void Win32GetDirFromPath(char *dst, UINT size, char *src)
+{
+	char str[MAX_SIZE];
+	int i,len;
+	char c;
+	char tmp[MAX_SIZE];
+	int wp;
+	if (src)
+	{
+		StrCpy(str, sizeof(str), src);
+	}
+	else
+	{
+		StrCpy(str, sizeof(str), dst);
+	}
+	Win32NukuEn(str, sizeof(str), NULL);
+	wp = 0;
+	len = StrLen(str);
+	dst[0] = 0;
+	for (i = 0;i < len;i++)
+	{
+		c = str[i];
+		switch (c)
+		{
+		case '\\':
+			tmp[wp] = 0;
+			wp = 0;
+			StrCat(dst, size, tmp);
+			StrCat(dst, size, "\\");
+			break;
+		default:
+			tmp[wp] = c;
+			wp++;
+			break;
+		}
+	}
+	Win32NukuEn(dst, size, NULL);
+}
+
+// ディレクトリの削除
+bool Win32DeleteDirW(wchar_t *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char *name_a = CopyUniToStr(name);
+		bool ret = Win32DeleteDir(name_a);
+
+		Free(name_a);
+
+		return ret;
+	}
+
+	if (RemoveDirectoryW(name) == FALSE)
+	{
+		return false;
+	}
+	return true;
+}
+bool Win32DeleteDir(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (RemoveDirectory(name) == FALSE)
+	{
+		return false;
+	}
+	return true;
+}
+
+// ディレクトリの作成
+bool Win32MakeDirW(wchar_t *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		char *name_a = CopyUniToStr(name);
+		bool ret = Win32MakeDir(name_a);
+
+		Free(name_a);
+
+		return ret;
+	}
+
+	if (CreateDirectoryW(name, NULL) == FALSE)
+	{
+		return false;
+	}
+
+	return true;
+}
+bool Win32MakeDir(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (CreateDirectory(name, NULL) == FALSE)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ファイルの削除
+bool Win32FileDeleteW(wchar_t *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (IsNt() == false)
+	{
+		bool ret;
+		char *name_a = CopyUniToStr(name);
+
+		ret = Win32FileDelete(name_a);
+
+		Free(name_a);
+
+		return ret;
+	}
+
+	if (DeleteFileW(name) == FALSE)
+	{
+		return false;
+	}
+	return true;
+}
+bool Win32FileDelete(char *name)
+{
+	// 引数チェック
+	if (name == NULL)
+	{
+		return false;
+	}
+
+	if (DeleteFile(name) == FALSE)
+	{
+		return false;
+	}
+	return true;
+}
+
+// ファイルのシーク
+bool Win32FileSeek(void *pData, UINT mode, int offset)
+{
+	WIN32IO *p;
+	DWORD ret;
+	// 引数チェック
+	if (pData == NULL)
+	{
+		return false;
+	}
+	if (mode != FILE_BEGIN && mode != FILE_END && mode != FILE_CURRENT)
+	{
+		return false;
+	}
+
+	p = (WIN32IO *)pData;
+	ret = SetFilePointer(p->hFile, (LONG)offset, NULL, mode);
+	if (ret == INVALID_SET_FILE_POINTER || ret == ERROR_NEGATIVE_SEEK)
+	{
+		return false;
+	}
+	return true;
+}
+
+// ファイルサイズの取得
+UINT64 Win32FileSize(void *pData)
+{
+	WIN32IO *p;
+	UINT64 ret;
+	DWORD tmp;
+	// 引数チェック
+	if (pData == NULL)
+	{
+		return 0;
+	}
+
+	p = (WIN32IO *)pData;
+	tmp = 0;
+	ret = GetFileSize(p->hFile, &tmp);
+	if (ret == (DWORD)-1)
+	{
+		return 0;
+	}
+
+	if (tmp != 0)
+	{
+		ret += (UINT64)tmp * 4294967296ULL;
+	}
+
+	return ret;
+}
+
+// ファイルに書き込む
+bool Win32FileWrite(void *pData, void *buf, UINT size)
+{
+	WIN32IO *p;
+	DWORD write_size;
+	// 引数チェック
+	if (pData == NULL || buf == NULL || size == 0)
+	{
+		return false;
+	}
+
+	p = (WIN32IO *)pData;
+	if (WriteFile(p->hFile, buf, size, &write_size, NULL) == FALSE)
+	{
+		return false;
+	}
+
+	if (write_size != size)
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// ファイルから読み込む
+bool Win32FileRead(void *pData, void *buf, UINT size)
+{
+	WIN32IO *p;
+	DWORD read_size;
+	// 引数チェック
+	if (pData == NULL || buf == NULL || size == 0)
+	{
+		return false;
+	}
+
+	p = (WIN32IO *)pData;
+	if (ReadFile(p->hFile, buf, size, &read_size, NULL) == FALSE)
+	{
+		return false;
+	}
+
+	if (read_size != size)
+	{
+		return false;
+	}
+	
+	return true;;
+}
+
+// ファイルを閉じる
+void Win32FileClose(void *pData, bool no_flush)
+{
+	WIN32IO *p;
+	// 引数チェック
+	if (pData == NULL)
+	{
+		return;
+	}
+
+	p = (WIN32IO *)pData;
+	if (p->WriteMode && no_flush == false)
+	{
+		FlushFileBuffers(p->hFile);
+	}
+	CloseHandle(p->hFile);
+	p->hFile = NULL;
+
+	// メモリ解放
+	Win32MemoryFree(p);
+}
+
+// ファイルをフラッシュする
+void Win32FileFlush(void *pData)
+{
+	WIN32IO *p;
+	// 引数チェック
+	if (pData == NULL)
+	{
+		return;
+	}
+
+	p = (WIN32IO *)pData;
+	if (p->WriteMode)
+	{
+		FlushFileBuffers(p->hFile);
+	}
+}
+
+// ファイルを開く
+void *Win32FileOpenW(wchar_t *name, bool write_mode, bool read_lock)
+{
+	WIN32IO *p;
+	HANDLE h;
+	DWORD lock_mode;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	if (IsNt() == false)
+	{
+		void *ret;
+		char *name_a = CopyUniToStr(name);
+
+		ret = Win32FileOpen(name_a, write_mode, read_lock);
+
+		Free(name_a);
+
+		return ret;
+	}
+
+	if (write_mode)
+	{
+		lock_mode = FILE_SHARE_READ;
+	}
+	else
+	{
+		if (read_lock == false)
+		{
+			lock_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+		}
+		else
+		{
+			lock_mode = FILE_SHARE_READ;
+		}
+	}
+
+	// ファイルを開く
+	h = CreateFileW(name,
+		(write_mode ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ),
+		lock_mode,
+		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		UINT ret = GetLastError();
+		// 失敗
+		return NULL;
+	}
+
+	// メモリ確保
+	p = Win32MemoryAlloc(sizeof(WIN32IO));
+	// ハンドル格納
+	p->hFile = h;
+
+	p->WriteMode = write_mode;
+
+	return (void *)p;
+}
+void *Win32FileOpen(char *name, bool write_mode, bool read_lock)
+{
+	WIN32IO *p;
+	HANDLE h;
+	DWORD lock_mode;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	if (write_mode)
+	{
+		lock_mode = FILE_SHARE_READ;
+	}
+	else
+	{
+		if (read_lock == false)
+		{
+			lock_mode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+		}
+		else
+		{
+			lock_mode = FILE_SHARE_READ;
+		}
+	}
+
+	// ファイルを開く
+	h = CreateFile(name,
+		(write_mode ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ),
+		lock_mode,
+		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		UINT ret = GetLastError();
+		// 失敗
+		return NULL;
+	}
+
+	// メモリ確保
+	p = Win32MemoryAlloc(sizeof(WIN32IO));
+	// ハンドル格納
+	p->hFile = h;
+
+	p->WriteMode = write_mode;
+
+	return (void *)p;
+}
+
+// ファイルを作成する
+void *Win32FileCreateW(wchar_t *name)
+{
+	WIN32IO *p;
+	HANDLE h;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	if (IsNt() == false)
+	{
+		void *ret;
+		char *name_a = CopyUniToStr(name);
+
+		ret = Win32FileCreate(name_a);
+
+		Free(name_a);
+
+		return ret;
+	}
+
+	// ファイルを作成する
+	h = CreateFileW(name, GENERIC_READ | GENERIC_WRITE,
+		FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
+		NULL);
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		h = CreateFileW(name, GENERIC_READ | GENERIC_WRITE,
+			FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN,
+			NULL);
+		if (h == INVALID_HANDLE_VALUE)
+		{
+			return NULL;
+		}
+	}
+
+	// メモリ確保
+	p = Win32MemoryAlloc(sizeof(WIN32IO));
+	// ハンドル格納
+	p->hFile = h;
+
+	p->WriteMode = true;
+
+	return (void *)p;
+}
+void *Win32FileCreate(char *name)
+{
+	WIN32IO *p;
+	HANDLE h;
+	// 引数チェック
+	if (name == NULL)
+	{
+		return NULL;
+	}
+
+	// ファイルを作成する
+	h = CreateFile(name, GENERIC_READ | GENERIC_WRITE,
+		FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
+		NULL);
+	if (h == INVALID_HANDLE_VALUE)
+	{
+		h = CreateFile(name, GENERIC_READ | GENERIC_WRITE,
+			FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN,
+			NULL);
+		if (h == INVALID_HANDLE_VALUE)
+		{
+			return NULL;
+		}
+	}
+
+	// メモリ確保
+	p = Win32MemoryAlloc(sizeof(WIN32IO));
+	// ハンドル格納
+	p->hFile = h;
+
+	p->WriteMode = true;
+
+	return (void *)p;
+}
+
+#define	SIZE_OF_CALLSTACK_SYM	10000
+#define	CALLSTACK_DEPTH			12
+
+// コールスタックの取得
+CALLSTACK_DATA *Win32GetCallStack()
+{
+#ifndef	WIN32_NO_DEBUG_HELP_DLL
+	DWORD current_eip32 = 0, current_esp32 = 0, current_ebp32 = 0;
+	UINT64 current_eip = 0, current_esp = 0, current_ebp = 0;
+	STACKFRAME64 sf;
+	CALLSTACK_DATA *cs = NULL, *s;
+
+#ifdef	CPU_64
+	CONTEXT context;
+#endif	// CPU_64
+
+	bool ret;
+	UINT depth = 0;
+
+#ifndef	CPU_64
+	// レジスタ取得 (32 bit)
+	__asm
+	{
+		mov current_esp32, esp
+		mov current_ebp32, ebp
+	};
+
+	current_eip32 = (DWORD)Win32GetCallStack;
+
+	current_eip = (UINT64)current_eip32;
+	current_esp = (UINT64)current_esp32;
+	current_ebp = (UINT64)current_ebp32;
+#else	// CPU_64
+	// レジスタ取得 (64 bit)
+	Zero(&context, sizeof(context));
+	context.ContextFlags = CONTEXT_FULL;
+	RtlCaptureContext(&context);
+#endif	// CPU_64
+
+	Zero(&sf, sizeof(sf));
+
+#ifndef	CPU_64
+	sf.AddrPC.Offset = current_eip;
+	sf.AddrStack.Offset = current_esp;
+	sf.AddrFrame.Offset = current_ebp;
+#else	// CPU_64
+	sf.AddrPC.Offset = context.Rip;
+	sf.AddrStack.Offset = context.Rsp;
+	sf.AddrFrame.Offset = context.Rsp;
+#endif	// CPU_64
+
+	sf.AddrPC.Mode = AddrModeFlat;
+	sf.AddrStack.Mode = AddrModeFlat;
+	sf.AddrFrame.Mode = AddrModeFlat;
+
+	while (true)
+	{
+		DWORD type = IMAGE_FILE_MACHINE_I386;
+
+#ifdef	CPU_64
+		type = IMAGE_FILE_MACHINE_AMD64;
+#endif	// CPU_64
+
+		if ((depth++) >= CALLSTACK_DEPTH)
+		{
+			break;
+		}
+
+#ifndef	CPU_64
+		ret = StackWalk64(type,
+			hCurrentProcessHandle,
+			GetCurrentThread(),
+			&sf,
+			NULL, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL);
+#else	// CPU_64
+		ret = StackWalk64(type,
+			hCurrentProcessHandle,
+			GetCurrentThread(),
+			&sf,
+			&context, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL);
+#endif	// CPU_64
+		if (ret == false || sf.AddrFrame.Offset == 0)
+		{
+			break;
+		}
+
+		if (cs == NULL)
+		{
+			cs = OSMemoryAlloc(sizeof(CALLSTACK_DATA));
+			s = cs;
+		}
+		else
+		{
+			s->next = OSMemoryAlloc(sizeof(CALLSTACK_DATA));
+			s = s->next;
+		}
+		s->symbol_cache = false;
+		s->next = NULL;
+		s->offset = sf.AddrPC.Offset;
+		s->disp = 0;
+		s->name = NULL;
+		s->line = 0;
+		s->filename[0] = 0;
+	}
+
+	return cs;
+#else	// WIN32_NO_DEBUG_HELP_DLL
+	return NULL;
+#endif	// WIN32_NO_DEBUG_HELP_DLL
+}
+
+// コールスタックからシンボル情報を取得
+bool Win32GetCallStackSymbolInfo(CALLSTACK_DATA *s)
+{
+#ifdef	WIN32_NO_DEBUG_HELP_DLL
+	return false;
+#else	// WIN32_NO_DEBUG_HELP_DLL
+	UINT64 disp;
+	UINT disp32, len;
+	IMAGEHLP_SYMBOL64 *sym;
+	IMAGEHLP_LINE64 line;
+	char tmp[MAX_PATH];
+	// 引数チェック
+	if (s == NULL)
+	{
+		return false;
+	}
+
+	if (s->symbol_cache)
+	{
+		return true;
+	}
+
+	sym = OSMemoryAlloc(SIZE_OF_CALLSTACK_SYM);
+	sym->SizeOfStruct = SIZE_OF_CALLSTACK_SYM;
+	sym->MaxNameLength = SIZE_OF_CALLSTACK_SYM - sizeof(IMAGEHLP_SYMBOL64);
+
+	if (SymGetSymFromAddr64(hCurrentProcessHandle, s->offset, &disp, sym))
+	{
+		s->disp = disp;
+		s->name = OSMemoryAlloc((UINT)strlen(sym->Name) + 1);
+		lstrcpy(s->name, sym->Name);
+	}
+	else
+	{
+		s->disp = 0;
+		s->name = NULL;
+	}
+
+	Zero(&line, sizeof(line));
+	line.SizeOfStruct = sizeof(line);
+	if (SymGetLineFromAddr64(hCurrentProcessHandle, s->offset, &disp32, &line))
+	{
+		disp = (UINT64)disp32;
+		s->line = line.LineNumber;
+		lstrcpy(s->filename, line.FileName);
+		Win32GetDirFromPath(tmp, sizeof(tmp), s->filename);
+		len = lstrlen(tmp);
+		lstrcpy(tmp, &s->filename[len + 1]);
+		lstrcpy(s->filename, tmp);
+	}
+	else
+	{
+		s->line = 0;
+		s->filename[0] = 0;
+	}
+
+	OSMemoryFree(sym);
+
+	s->symbol_cache = true;
+
+	return true;
+#endif	// WIN32_NO_DEBUG_HELP_DLL
+}
+
+// デフォルトの Win32 スレッド
+DWORD CALLBACK Win32DefaultThreadProc(void *param)
+{
+	WIN32THREADSTARTUPINFO *info = (WIN32THREADSTARTUPINFO *)param;
+	// 引数チェック
+	if (info == NULL)
+	{
+		return 0;
+	}
+
+	Win32InitNewThread();
+
+	// スレッド関数の呼び出し
+	info->thread_proc(info->thread, info->param);
+
+	// 参照の解放
+	ReleaseThread(info->thread);
+
+	Win32MemoryFree(info);
+
+	FreeOpenSSLThreadState();
+
+	_endthreadex(0);
+	return 0;
+}
+
+// スレッドの終了を待機
+bool Win32WaitThread(THREAD *t)
+{
+	WIN32THREAD *w;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return false;
+	}
+	w = (WIN32THREAD *)t->pData;
+	if (w == NULL)
+	{
+		return false;
+	}
+
+	// スレッドイベントを待機する
+	if (WaitForSingleObject(w->hThread, INFINITE) == WAIT_OBJECT_0)
+	{
+		// スレッドがシグナル状態になった
+		return true;
+	}
+
+	// 待機失敗 (タイムアウト等)
+	return false;
+}
+
+// スレッドの解放
+void Win32FreeThread(THREAD *t)
+{
+	WIN32THREAD *w;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return;
+	}
+	w = (WIN32THREAD *)t->pData;
+	if (w == NULL)
+	{
+		return;
+	}
+
+	// ハンドルを閉じる
+	CloseHandle(w->hThread);
+
+	// メモリ解放
+	Win32MemoryFree(t->pData);
+	t->pData = NULL;
+}
+
+// スレッドの初期化
+bool Win32InitThread(THREAD *t)
+{
+	WIN32THREAD *w;
+	HANDLE hThread;
+	DWORD thread_id;
+	WIN32THREADSTARTUPINFO *info;
+	// 引数チェック
+	if (t == NULL)
+	{
+		return false;
+	}
+	if (t->thread_proc == NULL)
+	{
+		return false;
+	}
+
+	// スレッドデータ生成
+	w = Win32MemoryAlloc(sizeof(WIN32THREAD));
+
+	// 起動情報生成
+	info = Win32MemoryAlloc(sizeof(WIN32THREADSTARTUPINFO));
+	info->param = t->param;
+	info->thread_proc = t->thread_proc;
+	info->thread = t;
+	AddRef(t->ref);
+
+	// スレッド作成
+	t->pData = w;
+	hThread = (HANDLE)_beginthreadex(NULL, 0, Win32DefaultThreadProc, info, 0, &thread_id);
+	if (hThread == NULL)
+	{
+		// スレッド作成失敗
+		t->pData = NULL;
+		Release(t->ref);
+		Win32MemoryFree(info);
+		Win32MemoryFree(w);
+		return false;
+	}
+
+	// スレッド情報の保存
+	w->hThread = hThread;
+	w->thread_id = thread_id;
+
+	return true;
+}
+
+// Win32 用ライブラリの初期化
+void Win32Init()
+{
+	INITCOMMONCONTROLSEX c;
+	OSVERSIONINFO os;
+
+	// Windows NT かどうか取得する
+	Zero(&os, sizeof(os));
+	os.dwOSVersionInfoSize = sizeof(os);
+	GetVersionEx(&os);
+
+	if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
+	{
+		// NT 系
+		win32_is_nt = true;
+	}
+	else
+	{
+		// 9x 系
+		win32_is_nt = false;
+	}
+
+	// stdout を開く
+	if (hstdout == INVALID_HANDLE_VALUE)
+	{
+		hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
+	}
+
+	// stdin を開く
+	if (hstdin == INVALID_HANDLE_VALUE)
+	{
+		hstdin = GetStdHandle(STD_INPUT_HANDLE);
+	}
+
+	Win32InitNewThread();
+
+	CoInitialize(NULL);
+
+	InitializeCriticalSection(&fasttick_lock);
+
+#ifdef	WIN32_USE_HEAP_API_FOR_MEMORY
+	use_heap_api = true;
+#else	// WIN32_USE_HEAP_API_FOR_MEMORY
+	use_heap_api = false;
+#endif	// WIN32_USE_HEAP_API_FOR_MEMORY
+
+	if (MayaquaIsDotNetMode())
+	{
+		// .NET API 内からヒープ関係の API を呼び出すとクラッシュする
+		use_heap_api = false;
+	}
+
+	if (IsNt() == false)
+	{
+		// Win9x ではヒープ関係の API は使用しない
+		use_heap_api = false;
+	}
+
+	if (use_heap_api)
+	{
+		heap_handle = HeapCreate(0, 0, 0);
+	}
+
+	// プロセス擬似ハンドルの取得
+	hCurrentProcessHandle = GetCurrentProcess();
+
+	// カレントディレクトリの初期化
+	// Win32InitCurrentDir(); /* 行わない */
+
+	// シンボルハンドラの初期化
+	if (IsMemCheck())
+	{
+#ifndef	WIN32_NO_DEBUG_HELP_DLL
+		SymInitialize(hCurrentProcessHandle, NULL, TRUE);
+#endif	// WIN32_NO_DEBUG_HELP_DLL
+	}
+
+	// Common Control の初期化
+	Zero(&c, sizeof(INITCOMMONCONTROLSEX));
+	c.dwSize = sizeof(INITCOMMONCONTROLSEX);
+	c.dwICC = ICC_ANIMATE_CLASS | ICC_BAR_CLASSES | ICC_COOL_CLASSES |
+		ICC_DATE_CLASSES | ICC_HOTKEY_CLASS | ICC_INTERNET_CLASSES |
+		ICC_LISTVIEW_CLASSES | ICC_NATIVEFNTCTL_CLASS |
+		ICC_PAGESCROLLER_CLASS | ICC_PROGRESS_CLASS |
+		ICC_TAB_CLASSES | ICC_TREEVIEW_CLASSES | ICC_UPDOWN_CLASS | ICC_USEREX_CLASSES |
+		ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&c);
+}
+
+// Win32 用ライブラリの解放
+void Win32Free()
+{
+	// シンボルハンドラを閉じる
+	if (IsMemCheck())
+	{
+#ifndef	WIN32_NO_DEBUG_HELP_DLL
+		SymCleanup(hCurrentProcessHandle);
+#endif	// WIN32_NO_DEBUG_HELP_DLL
+	}
+
+	if (use_heap_api)
+	{
+		HeapDestroy(heap_handle);
+		heap_handle = NULL;
+	}
+
+	CoUninitialize();
+
+	DeleteCriticalSection(&fasttick_lock);
+}
+
+// メモリ確保
+void *Win32MemoryAlloc(UINT size)
+{
+	if (use_heap_api)
+	{
+		return HeapAlloc(heap_handle, 0, size);
+	}
+	else
+	{
+		return malloc(size);
+	}
+}
+
+// メモリ再確保
+void *Win32MemoryReAlloc(void *addr, UINT size)
+{
+	if (use_heap_api)
+	{
+		return HeapReAlloc(heap_handle, 0, addr, size);
+	}
+	else
+	{
+		return realloc(addr, size);
+	}
+}
+
+// メモリ確報
+void Win32MemoryFree(void *addr)
+{
+	if (use_heap_api)
+	{
+		HeapFree(heap_handle, 0, addr);
+	}
+	else
+	{
+		free(addr);
+	}
+}
+
+// システムタイマの取得
+UINT Win32GetTick()
+{
+	return (UINT)timeGetTime();
+}
+
+// システム時刻の取得
+void Win32GetSystemTime(SYSTEMTIME *system_time)
+{
+	// システム時刻の取得
+	GetSystemTime(system_time);
+}
+
+// 32bit 整数のインクリメント
+void Win32Inc32(UINT *value)
+{
+	InterlockedIncrement(value);
+}
+
+// 32bit 整数のデクリメント
+void Win32Dec32(UINT *value)
+{
+	InterlockedDecrement(value);
+}
+
+// スレッドの休止
+void Win32Sleep(UINT time)
+{
+	Sleep(time);
+}
+
+// ロックの作成
+LOCK *Win32NewLock()
+{
+	// メモリ確保
+	LOCK *lock = Win32MemoryAlloc(sizeof(LOCK));
+
+	// クリティカルセクション確保
+	CRITICAL_SECTION *critical_section = Win32MemoryAlloc(sizeof(CRITICAL_SECTION));
+
+	if (lock == NULL || critical_section == NULL)
+	{
+		Win32MemoryFree(lock);
+		Win32MemoryFree(critical_section);
+		return NULL;
+	}
+
+	// クリティカルセクション初期化
+	InitializeCriticalSection(critical_section);
+
+	lock->pData = (void *)critical_section;
+	lock->Ready = true;
+
+	return lock;
+}
+
+// ロック
+bool Win32Lock(LOCK *lock)
+{
+	CRITICAL_SECTION *critical_section;
+	if (lock->Ready == false)
+	{
+		// 状態が不正
+		return false;
+	}
+
+	// クリティカルセクションに入る
+	critical_section = (CRITICAL_SECTION *)lock->pData;
+	EnterCriticalSection(critical_section);
+
+	return true;
+}
+
+// ロック解除
+void Win32Unlock(LOCK *lock)
+{
+	Win32UnlockEx(lock, false);
+}
+void Win32UnlockEx(LOCK *lock, bool inner)
+{
+	CRITICAL_SECTION *critical_section;
+	if (lock->Ready == false && inner == false)
+	{
+		// 状態が不正
+		return;
+	}
+
+	// クリティカルセクションから出る
+	critical_section = (CRITICAL_SECTION *)lock->pData;
+	LeaveCriticalSection(critical_section);
+}
+
+// ロックの削除
+void Win32DeleteLock(LOCK *lock)
+{
+	CRITICAL_SECTION *critical_section;
+	// Ready フラグを安全に解除する
+	Win32Lock(lock);
+	lock->Ready = false;
+	Win32UnlockEx(lock, true);
+
+	// クリティカルセクションの削除
+	critical_section = (CRITICAL_SECTION *)lock->pData;
+	DeleteCriticalSection(critical_section);
+
+	// メモリ解放
+	Win32MemoryFree(critical_section);
+	Win32MemoryFree(lock);
+}
+
+// イベントの初期化
+void Win32InitEvent(EVENT *event)
+{
+	// 自動リセットイベントの作成
+	HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+
+	event->pData = hEvent;
+}
+
+// イベントのセット
+void Win32SetEvent(EVENT *event)
+{
+	HANDLE hEvent = (HANDLE)event->pData;
+	if (hEvent == NULL)
+	{
+		return;
+	}
+
+	SetEvent(hEvent);
+}
+
+// イベントのリセット
+void Win32ResetEvent(EVENT *event)
+{
+	HANDLE hEvent = (HANDLE)event->pData;
+	if (hEvent == NULL)
+	{
+		return;
+	}
+
+	ResetEvent(hEvent);
+}
+
+// イベントを待機する
+bool Win32WaitEvent(EVENT *event, UINT timeout)
+{
+	HANDLE hEvent = (HANDLE)event->pData;
+	UINT ret;
+	if (hEvent == NULL)
+	{
+		return false;
+	}
+
+	// オブジェクトを待機
+	ret = WaitForSingleObject(hEvent, timeout);
+	if (ret == WAIT_TIMEOUT)
+	{
+		// タイムアウト
+		return false;
+	}
+	else
+	{
+		// シグナル状態
+		return true;
+	}
+}
+
+// イベントの解放
+void Win32FreeEvent(EVENT *event)
+{
+	HANDLE hEvent = (HANDLE)event->pData;
+	if (hEvent == NULL)
+	{
+		return;
+	}
+
+	CloseHandle(hEvent);
+}
+
+// Win32 専用の高速な 64 bit Tick 取得関数
+UINT64 Win32FastTick64()
+{
+	static UINT last_tick = 0;
+	static UINT counter = 0;
+	UINT64 ret;
+	UINT tick;
+
+	EnterCriticalSection(&fasttick_lock);
+
+	// 現在の tick 値を取得する
+	tick = Win32GetTick();
+
+	if (last_tick > tick)
+	{
+		// 前回取得した tick 値のほうが今回取得した値よりも大きい場合
+		// カウンタが 1 回りしたと考えることができる
+
+		counter++;
+	}
+
+	last_tick = tick;
+
+	ret = (UINT64)tick + (UINT64)counter * 4294967296ULL;
+
+	LeaveCriticalSection(&fasttick_lock);
+
+	if (start_tick == 0)
+	{
+		start_tick = ret;
+		ret = 0;
+	}
+	else
+	{
+		ret -= start_tick;
+	}
+
+	return ret + 1;
+}
+
+// 文字列をコンソールから読み込む
+bool Win32InputW(wchar_t *str, UINT size)
+{
+	bool ret = false;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return false;
+	}
+	if (size == 0)
+	{
+		size = 0x7fffffff;
+	}
+
+	if (str == NULL || size <= sizeof(wchar_t))
+	{
+		if (str != NULL)
+		{
+			Zero(str, size);
+		}
+
+		return Win32InputFromFileW(NULL, 0);
+	}
+
+	if (IsNt())
+	{
+		DWORD read_size = 0;
+
+		if (ReadConsoleW(hstdin, str, (size - sizeof(wchar_t)), &read_size, NULL))
+		{
+			str[read_size] = 0;
+
+			UniTrimCrlf(str);
+
+			ret = true;
+		}
+		else
+		{
+			ret = Win32InputFromFileW(str, size);
+		}
+	}
+	else
+	{
+		DWORD read_size = 0;
+		UINT a_size = size / sizeof(wchar_t) + 16;
+		char *a;
+
+		a = ZeroMalloc(a_size);
+
+		if (ReadConsoleA(hstdin, a, a_size - 1, &read_size, NULL))
+		{
+			a[read_size] = 0;
+
+			StrToUni(str, size, a);
+
+			UniTrimCrlf(str);
+
+			ret = true;
+		}
+		else
+		{
+			ret = Win32InputFromFileW(str, size);
+		}
+
+		Free(a);
+	}
+
+	return ret;
+}
+// 1 行を標準入力から取得
+bool Win32InputFromFileW(wchar_t *str, UINT size)
+{
+	char *a;
+	if (str == NULL)
+	{
+		wchar_t tmp[MAX_SIZE];
+		Win32InputFromFileW(tmp, sizeof(tmp));
+		return false;
+	}
+
+	a = Win32InputFromFileLineA();
+	if (a == NULL)
+	{
+		UniStrCpy(str, size, L"");
+		return false;
+	}
+
+	UtfToUni(str, size, a);
+
+	UniTrimCrlf(str);
+
+	Free(a);
+
+	return true;
+}
+char *Win32InputFromFileLineA()
+{
+	BUF *b = NewBuf();
+	char zero = 0;
+	char *ret = NULL;
+	bool ok = true;
+
+	while (true)
+	{
+		char c;
+		UINT read_size = 0;
+
+		if (ReadFile(hstdin, &c, 1, &read_size, NULL) == false)
+		{
+			ok = false;
+			break;
+		}
+		if (read_size != 1)
+		{
+			ok = false;
+			break;
+		}
+
+		WriteBuf(b, &c, 1);
+
+		if (c == 10)
+		{
+			break;
+		}
+	}
+
+	WriteBuf(b, &zero, 1);
+
+	if (ok)
+	{
+		ret = CopyStr(b->Buf);
+	}
+
+	FreeBuf(b);
+
+	return ret;
+}
+
+// 文字列をコンソールにプリントする
+void Win32PrintW(wchar_t *str)
+{
+	DWORD write_size = 0;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	if (IsNt())
+	{
+		if (WriteConsoleW(hstdout, str, UniStrLen(str), &write_size, NULL) == false)
+		{
+			Win32PrintToFileW(str);
+		}
+	}
+	else
+	{
+		char *ansi_str = CopyUniToStr(str);
+
+		if (WriteConsoleA(hstdout, ansi_str, StrLen(ansi_str), &write_size, NULL) == false)
+		{
+			Win32PrintToFileW(str);
+		}
+
+		Free(ansi_str);
+	}
+}
+void Win32PrintToFileW(wchar_t *str)
+{
+	char *utf;
+	DWORD size = 0;
+	// 引数チェック
+	if (str == NULL)
+	{
+		return;
+	}
+
+	utf = CopyUniToUtf(str);
+
+	WriteFile(hstdout, utf, StrLen(utf), &size, NULL);
+
+	Free(utf);
+}
+
+
+#endif	// WIN32
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Win32.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Win32.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/Win32.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,190 @@
+// SoftEther UT-VPN SourceCode
+// 
+// Copyright (C) 2004-2010 SoftEther Corporation.
+// Copyright (C) 2004-2010 University of Tsukuba, Japan.
+// Copyright (C) 2003-2010 Daiyuu Nobori.
+// All Rights Reserved.
+// 
+// http://utvpn.tsukuba.ac.jp/
+// 
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// version 2 as published by the Free Software Foundation.
+// 
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License version 2
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+// 
+// このファイルは GPL バージョン 2 ライセンスで公開されています。
+// 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
+// することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
+// を除去することはできません。改変した著作物を配布する場合は、改変実施者の
+// 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
+// 
+// この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
+// ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
+// および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
+// ホストされています。
+// 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
+// および、試験または研究のために利用が行われることを想定して配布
+// しています。
+// SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
+// あります。
+// 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
+// の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
+// いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
+// ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
+// に組み込みさせていただきます。
+// 
+// GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
+// 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
+// 
+// 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
+// (SoftEther Corporation) およびその他の著作権保持者が保有しています。
+// ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
+// 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
+// ください。
+// 
+// お願い: どのような通信ソフトウェアにも通常は必ず未発見の
+// セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
+// UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
+// 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
+// および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
+// 公益保護にご協力いただきますようお願い申し上げます。
+// 
+// ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
+// 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
+// を保護するための努力を行います。
+// 
+// ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
+// 日本国内の脆弱性情報届出受付公的機関:
+//         独立行政法人 情報処理推進機構
+//         http://www.ipa.go.jp/security/vuln/report/
+// 
+// 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
+// 連絡先: http://www.softether.co.jp/jp/contact/
+
+// -----------------------------------------------
+// [ChangeLog]
+// 2010.05.20
+//  新規リリース by SoftEther
+// -----------------------------------------------
+
+// Win32.h
+// Win32.c のヘッダ
+
+#ifdef	OS_WIN32
+
+#ifndef	WIN32_H
+#define	WIN32_H
+
+// 関数プロトタイプ
+OS_DISPATCH_TABLE *Win32GetDispatchTable();
+
+void Win32Init();
+void Win32Free();
+void *Win32MemoryAlloc(UINT size);
+void *Win32MemoryReAlloc(void *addr, UINT size);
+void Win32MemoryFree(void *addr);
+UINT Win32GetTick();
+void Win32GetSystemTime(SYSTEMTIME *system_time);
+void Win32Inc32(UINT *value);
+void Win32Dec32(UINT *value);
+void Win32Sleep(UINT time);
+LOCK *Win32NewLock();
+bool Win32Lock(LOCK *lock);
+void Win32Unlock(LOCK *lock);
+void Win32DeleteLock(LOCK *lock);
+void Win32InitEvent(EVENT *event);
+void Win32SetEvent(EVENT *event);
+void Win32ResetEvent(EVENT *event);
+bool Win32WaitEvent(EVENT *event, UINT timeout);
+void Win32FreeEvent(EVENT *event);
+bool Win32WaitThread(THREAD *t);
+void Win32FreeThread(THREAD *t);
+bool Win32InitThread(THREAD *t);
+UINT Win32ThreadId();
+void *Win32FileOpen(char *name, bool write_mode, bool read_lock);
+void *Win32FileOpenW(wchar_t *name, bool write_mode, bool read_lock);
+void *Win32FileCreate(char *name);
+void *Win32FileCreateW(wchar_t *name);
+bool Win32FileWrite(void *pData, void *buf, UINT size);
+bool Win32FileRead(void *pData, void *buf, UINT size);
+void Win32FileClose(void *pData, bool no_flush);
+void Win32FileFlush(void *pData);
+UINT64 Win32FileSize(void *pData);
+bool Win32FileSeek(void *pData, UINT mode, int offset);
+bool Win32FileDelete(char *name);
+bool Win32FileDeleteW(wchar_t *name);
+bool Win32MakeDir(char *name);
+bool Win32MakeDirW(wchar_t *name);
+bool Win32DeleteDir(char *name);
+bool Win32DeleteDirW(wchar_t *name);
+CALLSTACK_DATA *Win32GetCallStack();
+bool Win32GetCallStackSymbolInfo(CALLSTACK_DATA *s);
+bool Win32FileRename(char *old_name, char *new_name);
+bool Win32FileRenameW(wchar_t *old_name, wchar_t *new_name);
+bool Win32Run(char *filename, char *arg, bool hide, bool wait);
+bool Win32RunW(wchar_t *filename, wchar_t *arg, bool hide, bool wait);
+void *Win32RunEx(char *filename, char *arg, bool hide);
+void *Win32RunEx2(char *filename, char *arg, bool hide, UINT *process_id);
+void *Win32RunEx3(char *filename, char *arg, bool hide, UINT *process_id, bool disableWow);
+void *Win32RunExW(wchar_t *filename, wchar_t *arg, bool hide);
+void *Win32RunEx2W(wchar_t *filename, wchar_t *arg, bool hide, UINT *process_id);
+void *Win32RunEx3W(wchar_t *filename, wchar_t *arg, bool hide, UINT *process_id, bool disableWow);
+bool Win32WaitProcess(void *h, UINT timeout);
+bool Win32IsProcessAlive(void *handle);
+bool Win32TerminateProcess(void *handle);
+void Win32CloseProcess(void *handle);
+bool Win32IsSupportedOs();
+void Win32GetOsInfo(OS_INFO *info);
+void Win32Alert(char *msg, char *caption);
+void Win32AlertW(wchar_t *msg, wchar_t *caption);
+void Win32DebugAlert(char *msg);
+char* Win32GetProductId();
+void Win32SetHighPriority();
+void Win32RestorePriority();
+void *Win32NewSingleInstance(char *instance_name);
+void Win32FreeSingleInstance(void *data);
+void Win32GetMemInfo(MEMINFO *info);
+void Win32Yield();
+
+void Win32UnlockEx(LOCK *lock, bool inner);
+UINT Win32GetOsType();
+UINT Win32GetSpVer(char *str);
+UINT Win32GetOsSpVer();
+void Win32NukuEn(char *dst, UINT size, char *src);
+void Win32NukuEnW(wchar_t *dst, UINT size, wchar_t *src);
+void Win32GetDirFromPath(char *dst, UINT size, char *src);
+void Win32GetDirFromPathW(wchar_t *dst, UINT size, wchar_t *src);
+void Win32GetExeDir(char *name, UINT size);
+void Win32GetExeDirW(wchar_t *name, UINT size);
+void Win32GetCurrentDir(char *dir, UINT size);
+void Win32GetCurrentDirW(wchar_t *dir, UINT size);
+void Win32GetExeName(char *name, UINT size);
+void Win32GetExeNameW(wchar_t *name, UINT size);
+DIRLIST *Win32EnumDirEx(char *dirname, COMPARE *compare);
+DIRLIST *Win32EnumDirExW(wchar_t *dirname, COMPARE *compare);
+bool Win32GetDiskFreeW(wchar_t *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size);
+bool Win32GetDiskFree(char *path, UINT64 *free_size, UINT64 *used_size, UINT64 *total_size);
+bool Win32SetFolderCompress(char *path, bool compressed);
+bool Win32SetFolderCompressW(wchar_t *path, bool compressed);
+UINT64 Win32FastTick64();
+void Win32InitNewThread();
+bool Win32IsNt();
+bool Win32InputW(wchar_t *str, UINT size);
+bool Win32InputFromFileW(wchar_t *str, UINT size);
+char *Win32InputFromFileLineA();
+void Win32PrintW(wchar_t *str);
+void Win32PrintToFileW(wchar_t *str);
+
+#endif	// WIN32_H
+
+#endif	// OS_WIN32
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/cryptoki.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/cryptoki.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/cryptoki.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,66 @@
+/* cryptoki.h include file for PKCS #11. */
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the 
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* This is a sample file containing the top level include directives
+ * for building Win32 Cryptoki libraries and applications.
+ */
+
+#ifndef ___CRYPTOKI_H_INC___
+#define ___CRYPTOKI_H_INC___
+
+#pragma pack(push, cryptoki, 1)
+
+/* Specifies that the function is a DLL entry point. */
+#define CK_IMPORT_SPEC __declspec(dllimport)
+
+/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do
+ * not define it in applications.
+ */
+#ifdef CRYPTOKI_EXPORTS
+/* Specified that the function is an exported DLL entry point. */
+#define CK_EXPORT_SPEC __declspec(dllexport) 
+#else
+#define CK_EXPORT_SPEC CK_IMPORT_SPEC 
+#endif
+
+/* Ensures the calling convention for Win32 builds */
+#define CK_CALL_SPEC __cdecl
+
+#define CK_PTR *
+
+#define CK_DEFINE_FUNCTION(returnType, name) \
+  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
+
+#define CK_DECLARE_FUNCTION(returnType, name) \
+  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
+
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+  returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
+
+#define CK_CALLBACK_FUNCTION(returnType, name) \
+  returnType (CK_CALL_SPEC CK_PTR name)
+
+#ifndef NULL_PTR
+#define NULL_PTR 0
+#endif
+
+#include "pkcs11.h"
+
+#pragma pack(pop, cryptoki)
+
+#endif /* ___CRYPTOKI_H_INC___ */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/aes.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/aes.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/aes.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,127 @@
+/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ */
+
+#ifndef HEADER_AES_H
+#define HEADER_AES_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_AES
+#error AES is disabled.
+#endif
+
+#define AES_ENCRYPT	1
+#define AES_DECRYPT	0
+
+/* Because array size can't be a const in C, the following two are macros.
+   Both sizes are in bytes. */
+#define AES_MAXNR 14
+#define AES_BLOCK_SIZE 16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* This should be a hidden type, but EVP requires that the size be known */
+struct aes_key_st {
+#ifdef AES_LONG
+    unsigned long rd_key[4 *(AES_MAXNR + 1)];
+#else
+    unsigned int rd_key[4 *(AES_MAXNR + 1)];
+#endif
+    int rounds;
+};
+typedef struct aes_key_st AES_KEY;
+
+const char *AES_options(void);
+
+int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
+	AES_KEY *key);
+int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
+	AES_KEY *key);
+
+void AES_encrypt(const unsigned char *in, unsigned char *out,
+	const AES_KEY *key);
+void AES_decrypt(const unsigned char *in, unsigned char *out,
+	const AES_KEY *key);
+
+void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	const AES_KEY *key, const int enc);
+void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, const int enc);
+void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, int *num, const int enc);
+void AES_cfbr_encrypt_block(const unsigned char *in,unsigned char *out,
+			    const int nbits,const AES_KEY *key,
+			    unsigned char *ivec,const int enc);
+void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char *ivec, int *num);
+void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
+	const unsigned long length, const AES_KEY *key,
+	unsigned char ivec[AES_BLOCK_SIZE],
+	unsigned char ecount_buf[AES_BLOCK_SIZE],
+	unsigned int *num);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* !HEADER_AES_H */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/asn1.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/asn1.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/asn1.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,1230 @@
+/* crypto/asn1/asn1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ASN1_H
+#define HEADER_ASN1_H
+
+#include <time.h>
+#include <openssl/e_os2.h>
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+
+#include <openssl/symhacks.h>
+
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define V_ASN1_UNIVERSAL		0x00
+#define	V_ASN1_APPLICATION		0x40
+#define V_ASN1_CONTEXT_SPECIFIC		0x80
+#define V_ASN1_PRIVATE			0xc0
+
+#define V_ASN1_CONSTRUCTED		0x20
+#define V_ASN1_PRIMITIVE_TAG		0x1f
+#define V_ASN1_PRIMATIVE_TAG		0x1f
+
+#define V_ASN1_APP_CHOOSE		-2	/* let the recipient choose */
+#define V_ASN1_OTHER			-3	/* used in ASN1_TYPE */
+#define V_ASN1_ANY			-4	/* used in ASN1 template code */
+
+#define V_ASN1_NEG			0x100	/* negative flag */
+
+#define V_ASN1_UNDEF			-1
+#define V_ASN1_EOC			0
+#define V_ASN1_BOOLEAN			1	/**/
+#define V_ASN1_INTEGER			2
+#define V_ASN1_NEG_INTEGER		(2 | V_ASN1_NEG)
+#define V_ASN1_BIT_STRING		3
+#define V_ASN1_OCTET_STRING		4
+#define V_ASN1_NULL			5
+#define V_ASN1_OBJECT			6
+#define V_ASN1_OBJECT_DESCRIPTOR	7
+#define V_ASN1_EXTERNAL			8
+#define V_ASN1_REAL			9
+#define V_ASN1_ENUMERATED		10
+#define V_ASN1_NEG_ENUMERATED		(10 | V_ASN1_NEG)
+#define V_ASN1_UTF8STRING		12
+#define V_ASN1_SEQUENCE			16
+#define V_ASN1_SET			17
+#define V_ASN1_NUMERICSTRING		18	/**/
+#define V_ASN1_PRINTABLESTRING		19
+#define V_ASN1_T61STRING		20
+#define V_ASN1_TELETEXSTRING		20	/* alias */
+#define V_ASN1_VIDEOTEXSTRING		21	/**/
+#define V_ASN1_IA5STRING		22
+#define V_ASN1_UTCTIME			23
+#define V_ASN1_GENERALIZEDTIME		24	/**/
+#define V_ASN1_GRAPHICSTRING		25	/**/
+#define V_ASN1_ISO64STRING		26	/**/
+#define V_ASN1_VISIBLESTRING		26	/* alias */
+#define V_ASN1_GENERALSTRING		27	/**/
+#define V_ASN1_UNIVERSALSTRING		28	/**/
+#define V_ASN1_BMPSTRING		30
+
+/* For use with d2i_ASN1_type_bytes() */
+#define B_ASN1_NUMERICSTRING	0x0001
+#define B_ASN1_PRINTABLESTRING	0x0002
+#define B_ASN1_T61STRING	0x0004
+#define B_ASN1_TELETEXSTRING	0x0004
+#define B_ASN1_VIDEOTEXSTRING	0x0008
+#define B_ASN1_IA5STRING	0x0010
+#define B_ASN1_GRAPHICSTRING	0x0020
+#define B_ASN1_ISO64STRING	0x0040
+#define B_ASN1_VISIBLESTRING	0x0040
+#define B_ASN1_GENERALSTRING	0x0080
+#define B_ASN1_UNIVERSALSTRING	0x0100
+#define B_ASN1_OCTET_STRING	0x0200
+#define B_ASN1_BIT_STRING	0x0400
+#define B_ASN1_BMPSTRING	0x0800
+#define B_ASN1_UNKNOWN		0x1000
+#define B_ASN1_UTF8STRING	0x2000
+#define B_ASN1_UTCTIME		0x4000
+#define B_ASN1_GENERALIZEDTIME	0x8000
+
+/* For use with ASN1_mbstring_copy() */
+#define MBSTRING_FLAG		0x1000
+#define MBSTRING_UTF8		(MBSTRING_FLAG)
+#define MBSTRING_ASC		(MBSTRING_FLAG|1)
+#define MBSTRING_BMP		(MBSTRING_FLAG|2)
+#define MBSTRING_UNIV		(MBSTRING_FLAG|4)
+
+struct X509_algor_st;
+
+#define DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */
+#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */
+
+/* We MUST make sure that, except for constness, asn1_ctx_st and
+   asn1_const_ctx are exactly the same.  Fortunately, as soon as
+   the old ASN1 parsing macros are gone, we can throw this away
+   as well... */
+typedef struct asn1_ctx_st
+	{
+	unsigned char *p;/* work char pointer */
+	int eos;	/* end of sequence read for indefinite encoding */
+	int error;	/* error code to use when returning an error */
+	int inf;	/* constructed if 0x20, indefinite is 0x21 */
+	int tag;	/* tag from last 'get object' */
+	int xclass;	/* class from last 'get object' */
+	long slen;	/* length of last 'get object' */
+	unsigned char *max; /* largest value of p allowed */
+	unsigned char *q;/* temporary variable */
+	unsigned char **pp;/* variable */
+	int line;	/* used in error processing */
+	} ASN1_CTX;
+
+typedef struct asn1_const_ctx_st
+	{
+	const unsigned char *p;/* work char pointer */
+	int eos;	/* end of sequence read for indefinite encoding */
+	int error;	/* error code to use when returning an error */
+	int inf;	/* constructed if 0x20, indefinite is 0x21 */
+	int tag;	/* tag from last 'get object' */
+	int xclass;	/* class from last 'get object' */
+	long slen;	/* length of last 'get object' */
+	const unsigned char *max; /* largest value of p allowed */
+	const unsigned char *q;/* temporary variable */
+	const unsigned char **pp;/* variable */
+	int line;	/* used in error processing */
+	} ASN1_const_CTX;
+
+/* These are used internally in the ASN1_OBJECT to keep track of
+ * whether the names and data need to be free()ed */
+#define ASN1_OBJECT_FLAG_DYNAMIC	 0x01	/* internal use */
+#define ASN1_OBJECT_FLAG_CRITICAL	 0x02	/* critical x509v3 object id */
+#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04	/* internal use */
+#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 	 0x08	/* internal use */
+typedef struct asn1_object_st
+	{
+	const char *sn,*ln;
+	int nid;
+	int length;
+	unsigned char *data;
+	int flags;	/* Should we free this one */
+	} ASN1_OBJECT;
+
+#define ASN1_STRING_FLAG_BITS_LEFT 0x08 /* Set if 0x07 has bits left value */
+/* This indicates that the ASN1_STRING is not a real value but just a place
+ * holder for the location where indefinite length constructed data should
+ * be inserted in the memory buffer 
+ */
+#define ASN1_STRING_FLAG_NDEF 0x010 
+/* This is the base type that holds just about everything :-) */
+typedef struct asn1_string_st
+	{
+	int length;
+	int type;
+	unsigned char *data;
+	/* The value of the following field depends on the type being
+	 * held.  It is mostly being used for BIT_STRING so if the
+	 * input data has a non-zero 'unused bits' value, it will be
+	 * handled correctly */
+	long flags;
+	} ASN1_STRING;
+
+/* ASN1_ENCODING structure: this is used to save the received
+ * encoding of an ASN1 type. This is useful to get round
+ * problems with invalid encodings which can break signatures.
+ */
+
+typedef struct ASN1_ENCODING_st
+	{
+	unsigned char *enc;	/* DER encoding */
+	long len;		/* Length of encoding */
+	int modified;		 /* set to 1 if 'enc' is invalid */
+	} ASN1_ENCODING;
+
+/* Used with ASN1 LONG type: if a long is set to this it is omitted */
+#define ASN1_LONG_UNDEF	0x7fffffffL
+
+#define STABLE_FLAGS_MALLOC	0x01
+#define STABLE_NO_MASK		0x02
+#define DIRSTRING_TYPE	\
+ (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING)
+#define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING)
+
+typedef struct asn1_string_table_st {
+	int nid;
+	long minsize;
+	long maxsize;
+	unsigned long mask;
+	unsigned long flags;
+} ASN1_STRING_TABLE;
+
+DECLARE_STACK_OF(ASN1_STRING_TABLE)
+
+/* size limits: this stuff is taken straight from RFC2459 */
+
+#define ub_name				32768
+#define ub_common_name			64
+#define ub_locality_name		128
+#define ub_state_name			128
+#define ub_organization_name		64
+#define ub_organization_unit_name	64
+#define ub_title			64
+#define ub_email_address		128
+
+/* Declarations for template structures: for full definitions
+ * see asn1t.h
+ */
+typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE;
+typedef struct ASN1_ITEM_st ASN1_ITEM;
+typedef struct ASN1_TLC_st ASN1_TLC;
+/* This is just an opaque pointer */
+typedef struct ASN1_VALUE_st ASN1_VALUE;
+
+/* Declare ASN1 functions: the implement macro in in asn1t.h */
+
+#define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type)
+
+#define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type)
+
+#define DECLARE_ASN1_FUNCTIONS_name(type, name) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+	DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name)
+
+#define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \
+	DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name)
+
+#define	DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \
+	type *d2i_##name(type **a, const unsigned char **in, long len); \
+	int i2d_##name(type *a, unsigned char **out); \
+	DECLARE_ASN1_ITEM(itname)
+
+#define	DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \
+	type *d2i_##name(type **a, const unsigned char **in, long len); \
+	int i2d_##name(const type *a, unsigned char **out); \
+	DECLARE_ASN1_ITEM(name)
+
+#define	DECLARE_ASN1_NDEF_FUNCTION(name) \
+	int i2d_##name##_NDEF(name *a, unsigned char **out);
+
+#define DECLARE_ASN1_FUNCTIONS_const(name) \
+	name *name##_new(void); \
+	void name##_free(name *a);
+
+#define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \
+	type *name##_new(void); \
+	void name##_free(type *a);
+
+#define D2I_OF(type) type *(*)(type **,const unsigned char **,long)
+#define I2D_OF(type) int (*)(type *,unsigned char **)
+#define I2D_OF_const(type) int (*)(const type *,unsigned char **)
+
+#define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long)
+#define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **)
+#define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type)
+
+TYPEDEF_D2I2D_OF(void);
+
+/* The following macros and typedefs allow an ASN1_ITEM
+ * to be embedded in a structure and referenced. Since
+ * the ASN1_ITEM pointers need to be globally accessible
+ * (possibly from shared libraries) they may exist in
+ * different forms. On platforms that support it the
+ * ASN1_ITEM structure itself will be globally exported.
+ * Other platforms will export a function that returns
+ * an ASN1_ITEM pointer.
+ *
+ * To handle both cases transparently the macros below
+ * should be used instead of hard coding an ASN1_ITEM
+ * pointer in a structure.
+ *
+ * The structure will look like this:
+ *
+ * typedef struct SOMETHING_st {
+ *      ...
+ *      ASN1_ITEM_EXP *iptr;
+ *      ...
+ * } SOMETHING; 
+ *
+ * It would be initialised as e.g.:
+ *
+ * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...};
+ *
+ * and the actual pointer extracted with:
+ *
+ * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr);
+ *
+ * Finally an ASN1_ITEM pointer can be extracted from an
+ * appropriate reference with: ASN1_ITEM_rptr(X509). This
+ * would be used when a function takes an ASN1_ITEM * argument.
+ *
+ */
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM ASN1_ITEM_EXP;
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#define ASN1_ITEM_ptr(iptr) (iptr)
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#define ASN1_ITEM_ref(iptr) (&(iptr##_it))
+
+#define ASN1_ITEM_rptr(ref) (&(ref##_it))
+
+#define DECLARE_ASN1_ITEM(name) \
+	OPENSSL_EXTERN const ASN1_ITEM name##_it;
+
+#else
+
+/* Platforms that can't easily handle shared global variables are declared
+ * as functions returning ASN1_ITEM pointers.
+ */
+
+/* ASN1_ITEM pointer exported type */
+typedef const ASN1_ITEM * ASN1_ITEM_EXP(void);
+
+/* Macro to obtain ASN1_ITEM pointer from exported type */
+#define ASN1_ITEM_ptr(iptr) (iptr())
+
+/* Macro to include ASN1_ITEM pointer from base type */
+#define ASN1_ITEM_ref(iptr) (iptr##_it)
+
+#define ASN1_ITEM_rptr(ref) (ref##_it())
+
+#define DECLARE_ASN1_ITEM(name) \
+	const ASN1_ITEM * name##_it(void);
+
+#endif
+
+/* Parameters used by ASN1_STRING_print_ex() */
+
+/* These determine which characters to escape:
+ * RFC2253 special characters, control characters and
+ * MSB set characters
+ */
+
+#define ASN1_STRFLGS_ESC_2253		1
+#define ASN1_STRFLGS_ESC_CTRL		2
+#define ASN1_STRFLGS_ESC_MSB		4
+
+
+/* This flag determines how we do escaping: normally
+ * RC2253 backslash only, set this to use backslash and
+ * quote.
+ */
+
+#define ASN1_STRFLGS_ESC_QUOTE		8
+
+
+/* These three flags are internal use only. */
+
+/* Character is a valid PrintableString character */
+#define CHARTYPE_PRINTABLESTRING	0x10
+/* Character needs escaping if it is the first character */
+#define CHARTYPE_FIRST_ESC_2253		0x20
+/* Character needs escaping if it is the last character */
+#define CHARTYPE_LAST_ESC_2253		0x40
+
+/* NB the internal flags are safely reused below by flags
+ * handled at the top level.
+ */
+
+/* If this is set we convert all character strings
+ * to UTF8 first 
+ */
+
+#define ASN1_STRFLGS_UTF8_CONVERT	0x10
+
+/* If this is set we don't attempt to interpret content:
+ * just assume all strings are 1 byte per character. This
+ * will produce some pretty odd looking output!
+ */
+
+#define ASN1_STRFLGS_IGNORE_TYPE	0x20
+
+/* If this is set we include the string type in the output */
+#define ASN1_STRFLGS_SHOW_TYPE		0x40
+
+/* This determines which strings to display and which to
+ * 'dump' (hex dump of content octets or DER encoding). We can
+ * only dump non character strings or everything. If we
+ * don't dump 'unknown' they are interpreted as character
+ * strings with 1 octet per character and are subject to
+ * the usual escaping options.
+ */
+
+#define ASN1_STRFLGS_DUMP_ALL		0x80
+#define ASN1_STRFLGS_DUMP_UNKNOWN	0x100
+
+/* These determine what 'dumping' does, we can dump the
+ * content octets or the DER encoding: both use the
+ * RFC2253 #XXXXX notation.
+ */
+
+#define ASN1_STRFLGS_DUMP_DER		0x200
+
+/* All the string flags consistent with RFC2253,
+ * escaping control characters isn't essential in
+ * RFC2253 but it is advisable anyway.
+ */
+
+#define ASN1_STRFLGS_RFC2253	(ASN1_STRFLGS_ESC_2253 | \
+				ASN1_STRFLGS_ESC_CTRL | \
+				ASN1_STRFLGS_ESC_MSB | \
+				ASN1_STRFLGS_UTF8_CONVERT | \
+				ASN1_STRFLGS_DUMP_UNKNOWN | \
+				ASN1_STRFLGS_DUMP_DER)
+
+DECLARE_STACK_OF(ASN1_INTEGER)
+DECLARE_ASN1_SET_OF(ASN1_INTEGER)
+
+DECLARE_STACK_OF(ASN1_GENERALSTRING)
+
+typedef struct asn1_type_st
+	{
+	int type;
+	union	{
+		char *ptr;
+		ASN1_BOOLEAN		boolean;
+		ASN1_STRING *		asn1_string;
+		ASN1_OBJECT *		object;
+		ASN1_INTEGER *		integer;
+		ASN1_ENUMERATED *	enumerated;
+		ASN1_BIT_STRING *	bit_string;
+		ASN1_OCTET_STRING *	octet_string;
+		ASN1_PRINTABLESTRING *	printablestring;
+		ASN1_T61STRING *	t61string;
+		ASN1_IA5STRING *	ia5string;
+		ASN1_GENERALSTRING *	generalstring;
+		ASN1_BMPSTRING *	bmpstring;
+		ASN1_UNIVERSALSTRING *	universalstring;
+		ASN1_UTCTIME *		utctime;
+		ASN1_GENERALIZEDTIME *	generalizedtime;
+		ASN1_VISIBLESTRING *	visiblestring;
+		ASN1_UTF8STRING *	utf8string;
+		/* set and sequence are left complete and still
+		 * contain the set or sequence bytes */
+		ASN1_STRING *		set;
+		ASN1_STRING *		sequence;
+		} value;
+	} ASN1_TYPE;
+
+DECLARE_STACK_OF(ASN1_TYPE)
+DECLARE_ASN1_SET_OF(ASN1_TYPE)
+
+typedef struct asn1_method_st
+	{
+	i2d_of_void *i2d;
+	d2i_of_void *d2i;
+	void *(*create)(void);
+	void (*destroy)(void *);
+	} ASN1_METHOD;
+
+/* This is used when parsing some Netscape objects */
+typedef struct asn1_header_st
+	{
+	ASN1_OCTET_STRING *header;
+	void *data;
+	ASN1_METHOD *meth;
+	} ASN1_HEADER;
+
+/* This is used to contain a list of bit names */
+typedef struct BIT_STRING_BITNAME_st {
+	int bitnum;
+	const char *lname;
+	const char *sname;
+} BIT_STRING_BITNAME;
+
+
+#define M_ASN1_STRING_length(x)	((x)->length)
+#define M_ASN1_STRING_length_set(x, n)	((x)->length = (n))
+#define M_ASN1_STRING_type(x)	((x)->type)
+#define M_ASN1_STRING_data(x)	((x)->data)
+
+/* Macros for string operations */
+#define M_ASN1_BIT_STRING_new()	(ASN1_BIT_STRING *)\
+		ASN1_STRING_type_new(V_ASN1_BIT_STRING)
+#define M_ASN1_BIT_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\
+		ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+#define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c)
+
+#define M_ASN1_INTEGER_new()	(ASN1_INTEGER *)\
+		ASN1_STRING_type_new(V_ASN1_INTEGER)
+#define M_ASN1_INTEGER_free(a)		ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_INTEGER_cmp(a,b)	ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+
+#define M_ASN1_ENUMERATED_new()	(ASN1_ENUMERATED *)\
+		ASN1_STRING_type_new(V_ASN1_ENUMERATED)
+#define M_ASN1_ENUMERATED_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_ENUMERATED_cmp(a,b)	ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+
+#define M_ASN1_OCTET_STRING_new()	(ASN1_OCTET_STRING *)\
+		ASN1_STRING_type_new(V_ASN1_OCTET_STRING)
+#define M_ASN1_OCTET_STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\
+		ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\
+		(ASN1_STRING *)a,(ASN1_STRING *)b)
+#define M_ASN1_OCTET_STRING_set(a,b,c)	ASN1_STRING_set((ASN1_STRING *)a,b,c)
+#define M_ASN1_OCTET_STRING_print(a,b)	ASN1_STRING_print(a,(ASN1_STRING *)b)
+#define M_i2d_ASN1_OCTET_STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\
+		V_ASN1_UNIVERSAL)
+
+#define B_ASN1_TIME \
+			B_ASN1_UTCTIME | \
+			B_ASN1_GENERALIZEDTIME
+
+#define B_ASN1_PRINTABLE \
+			B_ASN1_PRINTABLESTRING| \
+			B_ASN1_T61STRING| \
+			B_ASN1_IA5STRING| \
+			B_ASN1_BIT_STRING| \
+			B_ASN1_UNIVERSALSTRING|\
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UTF8STRING|\
+			B_ASN1_UNKNOWN
+
+#define B_ASN1_DIRECTORYSTRING \
+			B_ASN1_PRINTABLESTRING| \
+			B_ASN1_TELETEXSTRING|\
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UNIVERSALSTRING|\
+			B_ASN1_UTF8STRING
+
+#define B_ASN1_DISPLAYTEXT \
+			B_ASN1_IA5STRING| \
+			B_ASN1_VISIBLESTRING| \
+			B_ASN1_BMPSTRING|\
+			B_ASN1_UTF8STRING
+
+#define M_ASN1_PRINTABLE_new()	ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_PRINTABLE_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+		pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLE(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_PRINTABLE)
+
+#define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_DIRECTORYSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+						pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DIRECTORYSTRING(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_DIRECTORYSTRING)
+
+#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\
+						pp,a->type,V_ASN1_UNIVERSAL)
+#define M_d2i_DISPLAYTEXT(a,pp,l) \
+		d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \
+			B_ASN1_DISPLAYTEXT)
+
+#define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\
+		ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING)
+#define M_ASN1_PRINTABLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_PRINTABLESTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\
+		V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \
+		(ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING)
+
+#define M_ASN1_T61STRING_new()	(ASN1_T61STRING *)\
+		ASN1_STRING_type_new(V_ASN1_T61STRING)
+#define M_ASN1_T61STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_T61STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\
+		V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_T61STRING(a,pp,l) \
+		(ASN1_T61STRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING)
+
+#define M_ASN1_IA5STRING_new()	(ASN1_IA5STRING *)\
+		ASN1_STRING_type_new(V_ASN1_IA5STRING)
+#define M_ASN1_IA5STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_IA5STRING_dup(a)	\
+			(ASN1_IA5STRING *)ASN1_STRING_dup((ASN1_STRING *)a)
+#define M_i2d_ASN1_IA5STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_IA5STRING(a,pp,l) \
+		(ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\
+			B_ASN1_IA5STRING)
+
+#define M_ASN1_UTCTIME_new()	(ASN1_UTCTIME *)\
+		ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_UTCTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+
+#define M_ASN1_GENERALIZEDTIME_new()	(ASN1_GENERALIZEDTIME *)\
+		ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME)
+#define M_ASN1_GENERALIZEDTIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\
+	(ASN1_STRING *)a)
+
+#define M_ASN1_TIME_new()	(ASN1_TIME *)\
+		ASN1_STRING_type_new(V_ASN1_UTCTIME)
+#define M_ASN1_TIME_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_ASN1_TIME_dup(a) (ASN1_TIME *)ASN1_STRING_dup((ASN1_STRING *)a)
+
+#define M_ASN1_GENERALSTRING_new()	(ASN1_GENERALSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_GENERALSTRING)
+#define M_ASN1_GENERALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_GENERALSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_GENERALSTRING(a,pp,l) \
+		(ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING)
+
+#define M_ASN1_UNIVERSALSTRING_new()	(ASN1_UNIVERSALSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING)
+#define M_ASN1_UNIVERSALSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \
+		(ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING)
+
+#define M_ASN1_BMPSTRING_new()	(ASN1_BMPSTRING *)\
+		ASN1_STRING_type_new(V_ASN1_BMPSTRING)
+#define M_ASN1_BMPSTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_BMPSTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_BMPSTRING(a,pp,l) \
+		(ASN1_BMPSTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING)
+
+#define M_ASN1_VISIBLESTRING_new()	(ASN1_VISIBLESTRING *)\
+		ASN1_STRING_type_new(V_ASN1_VISIBLESTRING)
+#define M_ASN1_VISIBLESTRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_VISIBLESTRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \
+		(ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING)
+
+#define M_ASN1_UTF8STRING_new()	(ASN1_UTF8STRING *)\
+		ASN1_STRING_type_new(V_ASN1_UTF8STRING)
+#define M_ASN1_UTF8STRING_free(a)	ASN1_STRING_free((ASN1_STRING *)a)
+#define M_i2d_ASN1_UTF8STRING(a,pp) \
+		i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\
+			V_ASN1_UNIVERSAL)
+#define M_d2i_ASN1_UTF8STRING(a,pp,l) \
+		(ASN1_UTF8STRING *)d2i_ASN1_type_bytes\
+		((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING)
+
+  /* for the is_set parameter to i2d_ASN1_SET */
+#define IS_SEQUENCE	0
+#define IS_SET		1
+
+DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE)
+
+int ASN1_TYPE_get(ASN1_TYPE *a);
+void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value);
+
+ASN1_OBJECT *	ASN1_OBJECT_new(void );
+void		ASN1_OBJECT_free(ASN1_OBJECT *a);
+int		i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp);
+ASN1_OBJECT *	c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+			long length);
+ASN1_OBJECT *	d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp,
+			long length);
+
+DECLARE_ASN1_ITEM(ASN1_OBJECT)
+
+DECLARE_STACK_OF(ASN1_OBJECT)
+DECLARE_ASN1_SET_OF(ASN1_OBJECT)
+
+ASN1_STRING *	ASN1_STRING_new(void);
+void		ASN1_STRING_free(ASN1_STRING *a);
+ASN1_STRING *	ASN1_STRING_dup(ASN1_STRING *a);
+ASN1_STRING *	ASN1_STRING_type_new(int type );
+int 		ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b);
+  /* Since this is used to store all sorts of things, via macros, for now, make
+     its data void * */
+int 		ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
+int ASN1_STRING_length(ASN1_STRING *x);
+void ASN1_STRING_length_set(ASN1_STRING *x, int n);
+int ASN1_STRING_type(ASN1_STRING *x);
+unsigned char * ASN1_STRING_data(ASN1_STRING *x);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING)
+int		i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp);
+ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp,
+			long length);
+int		ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d,
+			int length );
+int		ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value);
+int		ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n);
+
+#ifndef OPENSSL_NO_BIO
+int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
+				BIT_STRING_BITNAME *tbl, int indent);
+#endif
+int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl);
+int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
+				BIT_STRING_BITNAME *tbl);
+
+int		i2d_ASN1_BOOLEAN(int a,unsigned char **pp);
+int 		d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER)
+int		i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
+ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp,
+			long length);
+ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp,
+			long length);
+ASN1_INTEGER *	ASN1_INTEGER_dup(ASN1_INTEGER *x);
+int ASN1_INTEGER_cmp(ASN1_INTEGER *x, ASN1_INTEGER *y);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
+
+int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
+ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t);
+int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str);
+int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
+#if 0
+time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
+#endif
+
+int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
+ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t);
+int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
+ASN1_OCTET_STRING *	ASN1_OCTET_STRING_dup(ASN1_OCTET_STRING *a);
+int 	ASN1_OCTET_STRING_cmp(ASN1_OCTET_STRING *a, ASN1_OCTET_STRING *b);
+int 	ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, int len);
+
+DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_NULL)
+DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING)
+
+int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
+int UTF8_putc(unsigned char *str, int len, unsigned long value);
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE)
+
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING)
+DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT)
+DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING)
+DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME)
+DECLARE_ASN1_FUNCTIONS(ASN1_TIME)
+
+DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF)
+
+ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t);
+int ASN1_TIME_check(ASN1_TIME *t);
+ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out);
+
+int i2d_ASN1_SET(STACK *a, unsigned char **pp,
+		 i2d_of_void *i2d, int ex_tag, int ex_class, int is_set);
+STACK *	d2i_ASN1_SET(STACK **a, const unsigned char **pp, long length,
+		     d2i_of_void *d2i, void (*free_func)(void *),
+		     int ex_tag, int ex_class);
+
+#ifndef OPENSSL_NO_BIO
+int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a);
+int a2i_ASN1_INTEGER(BIO *bp,ASN1_INTEGER *bs,char *buf,int size);
+int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a);
+int a2i_ASN1_ENUMERATED(BIO *bp,ASN1_ENUMERATED *bs,char *buf,int size);
+int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a);
+int a2i_ASN1_STRING(BIO *bp,ASN1_STRING *bs,char *buf,int size);
+int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type);
+#endif
+int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a);
+
+int a2d_ASN1_OBJECT(unsigned char *out,int olen, const char *buf, int num);
+ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len,
+	const char *sn, const char *ln);
+
+int ASN1_INTEGER_set(ASN1_INTEGER *a, long v);
+long ASN1_INTEGER_get(ASN1_INTEGER *a);
+ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
+BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
+
+int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v);
+long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a);
+ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai);
+BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn);
+
+/* General */
+/* given a string, return the correct type, max is the maximum length */
+int ASN1_PRINTABLE_type(const unsigned char *s, int max);
+
+int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass);
+ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
+	long length, int Ptag, int Pclass);
+unsigned long ASN1_tag2bit(int tag);
+/* type is one or more of the B_ASN1_ values. */
+ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a,const unsigned char **pp,
+		long length,int type);
+
+/* PARSING */
+int asn1_Finish(ASN1_CTX *c);
+int asn1_const_Finish(ASN1_const_CTX *c);
+
+/* SPECIALS */
+int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
+	int *pclass, long omax);
+int ASN1_check_infinite_end(unsigned char **p,long len);
+int ASN1_const_check_infinite_end(const unsigned char **p,long len);
+void ASN1_put_object(unsigned char **pp, int constructed, int length,
+	int tag, int xclass);
+int ASN1_put_eoc(unsigned char **pp);
+int ASN1_object_size(int constructed, int length, int tag);
+
+/* Used to implement other functions */
+void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
+#define ASN1_dup_of(type,i2d,d2i,x) \
+	((type *(*)(I2D_OF(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x)
+#define ASN1_dup_of_const(type,i2d,d2i,x) \
+	((type *(*)(I2D_OF_const(type),D2I_OF(type),type *))openssl_fcast(ASN1_dup))(i2d,d2i,x)
+
+void *ASN1_item_dup(const ASN1_ITEM *it, void *x);
+
+#ifndef OPENSSL_NO_FP_API
+void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x);
+#define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \
+	((type *(*)(type *(*)(void),D2I_OF(type),FILE *,type **))openssl_fcast(ASN1_d2i_fp))(xnew,d2i,in,x)
+void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x);
+int ASN1_i2d_fp(i2d_of_void *i2d,FILE *out,void *x);
+#define ASN1_i2d_fp_of(type,i2d,out,x) \
+	((int (*)(I2D_OF(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x)
+#define ASN1_i2d_fp_of_const(type,i2d,out,x) \
+	((int (*)(I2D_OF_const(type),FILE *,type *))openssl_fcast(ASN1_i2d_fp))(i2d,out,x)
+int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x);
+int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags);
+#endif
+
+int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in);
+
+#ifndef OPENSSL_NO_BIO
+void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x);
+#define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \
+	((type *(*)(type *(*)(void),D2I_OF(type),BIO *,type **))openssl_fcast(ASN1_d2i_bio))(xnew,d2i,in,x)
+void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
+int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
+#define ASN1_i2d_bio_of(type,i2d,out,x) \
+	((int (*)(I2D_OF(type),BIO *,type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x)
+#define ASN1_i2d_bio_of_const(type,i2d,out,x) \
+	((int (*)(I2D_OF_const(type),BIO *,const type *))openssl_fcast(ASN1_i2d_bio))(i2d,out,x)
+int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x);
+int ASN1_UTCTIME_print(BIO *fp,ASN1_UTCTIME *a);
+int ASN1_GENERALIZEDTIME_print(BIO *fp,ASN1_GENERALIZEDTIME *a);
+int ASN1_TIME_print(BIO *fp,ASN1_TIME *a);
+int ASN1_STRING_print(BIO *bp,ASN1_STRING *v);
+int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags);
+int ASN1_parse(BIO *bp,const unsigned char *pp,long len,int indent);
+int ASN1_parse_dump(BIO *bp,const unsigned char *pp,long len,int indent,int dump);
+#endif
+const char *ASN1_tag2str(int tag);
+
+/* Used to load and write netscape format cert/key */
+int i2d_ASN1_HEADER(ASN1_HEADER *a,unsigned char **pp);
+ASN1_HEADER *d2i_ASN1_HEADER(ASN1_HEADER **a,const unsigned char **pp, long length);
+ASN1_HEADER *ASN1_HEADER_new(void );
+void ASN1_HEADER_free(ASN1_HEADER *a);
+
+int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s);
+
+/* Not used that much at this point, except for the first two */
+ASN1_METHOD *X509_asn1_meth(void);
+ASN1_METHOD *RSAPrivateKey_asn1_meth(void);
+ASN1_METHOD *ASN1_IA5STRING_asn1_meth(void);
+ASN1_METHOD *ASN1_BIT_STRING_asn1_meth(void);
+
+int ASN1_TYPE_set_octetstring(ASN1_TYPE *a,
+	unsigned char *data, int len);
+int ASN1_TYPE_get_octetstring(ASN1_TYPE *a,
+	unsigned char *data, int max_len);
+int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num,
+	unsigned char *data, int len);
+int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a,long *num,
+	unsigned char *data, int max_len);
+
+STACK *ASN1_seq_unpack(const unsigned char *buf, int len,
+		       d2i_of_void *d2i, void (*free_func)(void *));
+unsigned char *ASN1_seq_pack(STACK *safes, i2d_of_void *i2d,
+			     unsigned char **buf, int *len );
+void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i);
+void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it);
+ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d,
+			      ASN1_OCTET_STRING **oct);
+#define ASN1_pack_string_of(type,obj,i2d,oct) \
+	((ASN1_STRING *(*)(type *,I2D_OF(type),ASN1_OCTET_STRING **))openssl_fcast(ASN1_pack_string))(obj,i2d,oct)
+ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);
+
+void ASN1_STRING_set_default_mask(unsigned long mask);
+int ASN1_STRING_set_default_mask_asc(char *p);
+unsigned long ASN1_STRING_get_default_mask(void);
+int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask);
+int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
+					int inform, unsigned long mask, 
+					long minsize, long maxsize);
+
+ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, 
+		const unsigned char *in, int inlen, int inform, int nid);
+ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid);
+int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long);
+void ASN1_STRING_TABLE_cleanup(void);
+
+/* ASN1 template functions */
+
+/* Old API compatible functions */
+ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it);
+void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it);
+ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it);
+int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it);
+
+void ASN1_add_oid_module(void);
+
+ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf);
+ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf);
+	
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ASN1_strings(void);
+
+/* Error codes for the ASN1 functions. */
+
+/* Function codes. */
+#define ASN1_F_A2D_ASN1_OBJECT				 100
+#define ASN1_F_A2I_ASN1_ENUMERATED			 101
+#define ASN1_F_A2I_ASN1_INTEGER				 102
+#define ASN1_F_A2I_ASN1_STRING				 103
+#define ASN1_F_APPEND_EXP				 176
+#define ASN1_F_ASN1_BIT_STRING_SET_BIT			 183
+#define ASN1_F_ASN1_CB					 177
+#define ASN1_F_ASN1_CHECK_TLEN				 104
+#define ASN1_F_ASN1_COLLATE_PRIMITIVE			 105
+#define ASN1_F_ASN1_COLLECT				 106
+#define ASN1_F_ASN1_D2I_EX_PRIMITIVE			 108
+#define ASN1_F_ASN1_D2I_FP				 109
+#define ASN1_F_ASN1_D2I_READ_BIO			 107
+#define ASN1_F_ASN1_DIGEST				 184
+#define ASN1_F_ASN1_DO_ADB				 110
+#define ASN1_F_ASN1_DUP					 111
+#define ASN1_F_ASN1_ENUMERATED_SET			 112
+#define ASN1_F_ASN1_ENUMERATED_TO_BN			 113
+#define ASN1_F_ASN1_EX_C2I				 204
+#define ASN1_F_ASN1_FIND_END				 190
+#define ASN1_F_ASN1_GENERALIZEDTIME_SET			 185
+#define ASN1_F_ASN1_GENERATE_V3				 178
+#define ASN1_F_ASN1_GET_OBJECT				 114
+#define ASN1_F_ASN1_HEADER_NEW				 115
+#define ASN1_F_ASN1_I2D_BIO				 116
+#define ASN1_F_ASN1_I2D_FP				 117
+#define ASN1_F_ASN1_INTEGER_SET				 118
+#define ASN1_F_ASN1_INTEGER_TO_BN			 119
+#define ASN1_F_ASN1_ITEM_D2I_FP				 190
+#define ASN1_F_ASN1_ITEM_DUP				 191
+#define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW			 121
+#define ASN1_F_ASN1_ITEM_EX_D2I				 120
+#define ASN1_F_ASN1_ITEM_I2D_BIO			 192
+#define ASN1_F_ASN1_ITEM_I2D_FP				 193
+#define ASN1_F_ASN1_ITEM_PACK				 198
+#define ASN1_F_ASN1_ITEM_SIGN				 195
+#define ASN1_F_ASN1_ITEM_UNPACK				 199
+#define ASN1_F_ASN1_ITEM_VERIFY				 197
+#define ASN1_F_ASN1_MBSTRING_NCOPY			 122
+#define ASN1_F_ASN1_OBJECT_NEW				 123
+#define ASN1_F_ASN1_PACK_STRING				 124
+#define ASN1_F_ASN1_PKCS5_PBE_SET			 125
+#define ASN1_F_ASN1_SEQ_PACK				 126
+#define ASN1_F_ASN1_SEQ_UNPACK				 127
+#define ASN1_F_ASN1_SIGN				 128
+#define ASN1_F_ASN1_STR2TYPE				 179
+#define ASN1_F_ASN1_STRING_SET				 186
+#define ASN1_F_ASN1_STRING_TABLE_ADD			 129
+#define ASN1_F_ASN1_STRING_TYPE_NEW			 130
+#define ASN1_F_ASN1_TEMPLATE_EX_D2I			 132
+#define ASN1_F_ASN1_TEMPLATE_NEW			 133
+#define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I			 131
+#define ASN1_F_ASN1_TIME_SET				 175
+#define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING		 134
+#define ASN1_F_ASN1_TYPE_GET_OCTETSTRING		 135
+#define ASN1_F_ASN1_UNPACK_STRING			 136
+#define ASN1_F_ASN1_UTCTIME_SET				 187
+#define ASN1_F_ASN1_VERIFY				 137
+#define ASN1_F_BITSTR_CB				 180
+#define ASN1_F_BN_TO_ASN1_ENUMERATED			 138
+#define ASN1_F_BN_TO_ASN1_INTEGER			 139
+#define ASN1_F_C2I_ASN1_BIT_STRING			 189
+#define ASN1_F_C2I_ASN1_INTEGER				 194
+#define ASN1_F_C2I_ASN1_OBJECT				 196
+#define ASN1_F_COLLECT_DATA				 140
+#define ASN1_F_D2I_ASN1_BIT_STRING			 141
+#define ASN1_F_D2I_ASN1_BOOLEAN				 142
+#define ASN1_F_D2I_ASN1_BYTES				 143
+#define ASN1_F_D2I_ASN1_GENERALIZEDTIME			 144
+#define ASN1_F_D2I_ASN1_HEADER				 145
+#define ASN1_F_D2I_ASN1_INTEGER				 146
+#define ASN1_F_D2I_ASN1_OBJECT				 147
+#define ASN1_F_D2I_ASN1_SET				 148
+#define ASN1_F_D2I_ASN1_TYPE_BYTES			 149
+#define ASN1_F_D2I_ASN1_UINTEGER			 150
+#define ASN1_F_D2I_ASN1_UTCTIME				 151
+#define ASN1_F_D2I_NETSCAPE_RSA				 152
+#define ASN1_F_D2I_NETSCAPE_RSA_2			 153
+#define ASN1_F_D2I_PRIVATEKEY				 154
+#define ASN1_F_D2I_PUBLICKEY				 155
+#define ASN1_F_D2I_RSA_NET				 200
+#define ASN1_F_D2I_RSA_NET_2				 201
+#define ASN1_F_D2I_X509					 156
+#define ASN1_F_D2I_X509_CINF				 157
+#define ASN1_F_D2I_X509_PKEY				 159
+#define ASN1_F_I2D_ASN1_SET				 188
+#define ASN1_F_I2D_ASN1_TIME				 160
+#define ASN1_F_I2D_DSA_PUBKEY				 161
+#define ASN1_F_I2D_EC_PUBKEY				 181
+#define ASN1_F_I2D_PRIVATEKEY				 163
+#define ASN1_F_I2D_PUBLICKEY				 164
+#define ASN1_F_I2D_RSA_NET				 162
+#define ASN1_F_I2D_RSA_PUBKEY				 165
+#define ASN1_F_LONG_C2I					 166
+#define ASN1_F_OID_MODULE_INIT				 174
+#define ASN1_F_PARSE_TAGGING				 182
+#define ASN1_F_PKCS5_PBE2_SET				 167
+#define ASN1_F_PKCS5_PBE_SET				 202
+#define ASN1_F_X509_CINF_NEW				 168
+#define ASN1_F_X509_CRL_ADD0_REVOKED			 169
+#define ASN1_F_X509_INFO_NEW				 170
+#define ASN1_F_X509_NAME_ENCODE				 203
+#define ASN1_F_X509_NAME_EX_D2I				 158
+#define ASN1_F_X509_NAME_EX_NEW				 171
+#define ASN1_F_X509_NEW					 172
+#define ASN1_F_X509_PKEY_NEW				 173
+
+/* Reason codes. */
+#define ASN1_R_ADDING_OBJECT				 171
+#define ASN1_R_AUX_ERROR				 100
+#define ASN1_R_BAD_CLASS				 101
+#define ASN1_R_BAD_OBJECT_HEADER			 102
+#define ASN1_R_BAD_PASSWORD_READ			 103
+#define ASN1_R_BAD_TAG					 104
+#define ASN1_R_BN_LIB					 105
+#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH			 106
+#define ASN1_R_BUFFER_TOO_SMALL				 107
+#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 108
+#define ASN1_R_DATA_IS_WRONG				 109
+#define ASN1_R_DECODE_ERROR				 110
+#define ASN1_R_DECODING_ERROR				 111
+#define ASN1_R_DEPTH_EXCEEDED				 174
+#define ASN1_R_ENCODE_ERROR				 112
+#define ASN1_R_ERROR_GETTING_TIME			 173
+#define ASN1_R_ERROR_LOADING_SECTION			 172
+#define ASN1_R_ERROR_PARSING_SET_ELEMENT		 113
+#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS		 114
+#define ASN1_R_EXPECTING_AN_INTEGER			 115
+#define ASN1_R_EXPECTING_AN_OBJECT			 116
+#define ASN1_R_EXPECTING_A_BOOLEAN			 117
+#define ASN1_R_EXPECTING_A_TIME				 118
+#define ASN1_R_EXPLICIT_LENGTH_MISMATCH			 119
+#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED		 120
+#define ASN1_R_FIELD_MISSING				 121
+#define ASN1_R_FIRST_NUM_TOO_LARGE			 122
+#define ASN1_R_HEADER_TOO_LONG				 123
+#define ASN1_R_ILLEGAL_BITSTRING_FORMAT			 175
+#define ASN1_R_ILLEGAL_BOOLEAN				 176
+#define ASN1_R_ILLEGAL_CHARACTERS			 124
+#define ASN1_R_ILLEGAL_FORMAT				 177
+#define ASN1_R_ILLEGAL_HEX				 178
+#define ASN1_R_ILLEGAL_IMPLICIT_TAG			 179
+#define ASN1_R_ILLEGAL_INTEGER				 180
+#define ASN1_R_ILLEGAL_NESTED_TAGGING			 181
+#define ASN1_R_ILLEGAL_NULL				 125
+#define ASN1_R_ILLEGAL_NULL_VALUE			 182
+#define ASN1_R_ILLEGAL_OBJECT				 183
+#define ASN1_R_ILLEGAL_OPTIONAL_ANY			 126
+#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE		 170
+#define ASN1_R_ILLEGAL_TAGGED_ANY			 127
+#define ASN1_R_ILLEGAL_TIME_VALUE			 184
+#define ASN1_R_INTEGER_NOT_ASCII_FORMAT			 185
+#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG		 128
+#define ASN1_R_INVALID_BMPSTRING_LENGTH			 129
+#define ASN1_R_INVALID_DIGIT				 130
+#define ASN1_R_INVALID_MODIFIER				 186
+#define ASN1_R_INVALID_NUMBER				 187
+#define ASN1_R_INVALID_SEPARATOR			 131
+#define ASN1_R_INVALID_TIME_FORMAT			 132
+#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH		 133
+#define ASN1_R_INVALID_UTF8STRING			 134
+#define ASN1_R_IV_TOO_LARGE				 135
+#define ASN1_R_LENGTH_ERROR				 136
+#define ASN1_R_LIST_ERROR				 188
+#define ASN1_R_MISSING_EOC				 137
+#define ASN1_R_MISSING_SECOND_NUMBER			 138
+#define ASN1_R_MISSING_VALUE				 189
+#define ASN1_R_MSTRING_NOT_UNIVERSAL			 139
+#define ASN1_R_MSTRING_WRONG_TAG			 140
+#define ASN1_R_NESTED_ASN1_STRING			 197
+#define ASN1_R_NON_HEX_CHARACTERS			 141
+#define ASN1_R_NOT_ASCII_FORMAT				 190
+#define ASN1_R_NOT_ENOUGH_DATA				 142
+#define ASN1_R_NO_MATCHING_CHOICE_TYPE			 143
+#define ASN1_R_NULL_IS_WRONG_LENGTH			 144
+#define ASN1_R_OBJECT_NOT_ASCII_FORMAT			 191
+#define ASN1_R_ODD_NUMBER_OF_CHARS			 145
+#define ASN1_R_PRIVATE_KEY_HEADER_MISSING		 146
+#define ASN1_R_SECOND_NUMBER_TOO_LARGE			 147
+#define ASN1_R_SEQUENCE_LENGTH_MISMATCH			 148
+#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED			 149
+#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG		 192
+#define ASN1_R_SHORT_LINE				 150
+#define ASN1_R_STRING_TOO_LONG				 151
+#define ASN1_R_STRING_TOO_SHORT				 152
+#define ASN1_R_TAG_VALUE_TOO_HIGH			 153
+#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154
+#define ASN1_R_TIME_NOT_ASCII_FORMAT			 193
+#define ASN1_R_TOO_LONG					 155
+#define ASN1_R_TYPE_NOT_CONSTRUCTED			 156
+#define ASN1_R_UNABLE_TO_DECODE_RSA_KEY			 157
+#define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY		 158
+#define ASN1_R_UNEXPECTED_EOC				 159
+#define ASN1_R_UNKNOWN_FORMAT				 160
+#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM		 161
+#define ASN1_R_UNKNOWN_OBJECT_TYPE			 162
+#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE			 163
+#define ASN1_R_UNKNOWN_TAG				 194
+#define ASN1_R_UNKOWN_FORMAT				 195
+#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE		 164
+#define ASN1_R_UNSUPPORTED_CIPHER			 165
+#define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM		 166
+#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE		 167
+#define ASN1_R_UNSUPPORTED_TYPE				 196
+#define ASN1_R_WRONG_TAG				 168
+#define ASN1_R_WRONG_TYPE				 169
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/asn1_mac.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/asn1_mac.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/asn1_mac.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,571 @@
+/* crypto/asn1/asn1_mac.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ASN1_MAC_H
+#define HEADER_ASN1_MAC_H
+
+#include <openssl/asn1.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifndef ASN1_MAC_ERR_LIB
+#define ASN1_MAC_ERR_LIB	ERR_LIB_ASN1
+#endif 
+
+#define ASN1_MAC_H_err(f,r,line) \
+	ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line))
+
+#define M_ASN1_D2I_vars(a,type,func) \
+	ASN1_const_CTX c; \
+	type ret=NULL; \
+	\
+	c.pp=(const unsigned char **)pp; \
+	c.q= *(const unsigned char **)pp; \
+	c.error=ERR_R_NESTED_ASN1_ERROR; \
+	if ((a == NULL) || ((*a) == NULL)) \
+		{ if ((ret=(type)func()) == NULL) \
+			{ c.line=__LINE__; goto err; } } \
+	else	ret=(*a);
+
+#define M_ASN1_D2I_Init() \
+	c.p= *(const unsigned char **)pp; \
+	c.max=(length == 0)?0:(c.p+length);
+
+#define M_ASN1_D2I_Finish_2(a) \
+	if (!asn1_const_Finish(&c)) \
+		{ c.line=__LINE__; goto err; } \
+	*(const unsigned char **)pp=c.p; \
+	if (a != NULL) (*a)=ret; \
+	return(ret);
+
+#define M_ASN1_D2I_Finish(a,func,e) \
+	M_ASN1_D2I_Finish_2(a); \
+err:\
+	ASN1_MAC_H_err((e),c.error,c.line); \
+	asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \
+	if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
+	return(NULL)
+
+#define M_ASN1_D2I_start_sequence() \
+	if (!asn1_GetSequence(&c,&length)) \
+		{ c.line=__LINE__; goto err; }
+/* Begin reading ASN1 without a surrounding sequence */
+#define M_ASN1_D2I_begin() \
+	c.slen = length;
+
+/* End reading ASN1 with no check on length */
+#define M_ASN1_D2I_Finish_nolen(a, func, e) \
+	*pp=c.p; \
+	if (a != NULL) (*a)=ret; \
+	return(ret); \
+err:\
+	ASN1_MAC_H_err((e),c.error,c.line); \
+	asn1_add_error(*pp,(int)(c.q- *pp)); \
+	if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \
+	return(NULL)
+
+#define M_ASN1_D2I_end_sequence() \
+	(((c.inf&1) == 0)?(c.slen <= 0): \
+		(c.eos=ASN1_const_check_infinite_end(&c.p,c.slen)))
+
+/* Don't use this with d2i_ASN1_BOOLEAN() */
+#define M_ASN1_D2I_get(b, func) \
+	c.q=c.p; \
+	if (func(&(b),&c.p,c.slen) == NULL) \
+		{c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+/* Don't use this with d2i_ASN1_BOOLEAN() */
+#define M_ASN1_D2I_get_x(type,b,func) \
+	c.q=c.p; \
+	if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \
+		{c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+/* use this instead () */
+#define M_ASN1_D2I_get_int(b,func) \
+	c.q=c.p; \
+	if (func(&(b),&c.p,c.slen) < 0) \
+		{c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_opt(b,func,type) \
+	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \
+		== (V_ASN1_UNIVERSAL|(type)))) \
+		{ \
+		M_ASN1_D2I_get(b,func); \
+		}
+
+#define M_ASN1_D2I_get_imp(b,func, type) \
+	M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \
+	c.q=c.p; \
+	if (func(&(b),&c.p,c.slen) == NULL) \
+		{c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \
+	c.slen-=(c.p-c.q);\
+	M_ASN1_next_prev=_tmp;
+
+#define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \
+	if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \
+		(V_ASN1_CONTEXT_SPECIFIC|(tag)))) \
+		{ \
+		unsigned char _tmp = M_ASN1_next; \
+		M_ASN1_D2I_get_imp(b,func, type);\
+		}
+
+#define M_ASN1_D2I_get_set(r,func,free_func) \
+		M_ASN1_D2I_get_imp_set(r,func,free_func, \
+			V_ASN1_SET,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_set_type(type,r,func,free_func) \
+		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \
+			V_ASN1_SET,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_set_opt(r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
+		{ M_ASN1_D2I_get_set(r,func,free_func); }
+
+#define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SET)))\
+		{ M_ASN1_D2I_get_set_type(type,r,func,free_func); }
+
+#define M_ASN1_I2D_len_SET_opt(a,f) \
+	if ((a != NULL) && (sk_num(a) != 0)) \
+		M_ASN1_I2D_len_SET(a,f);
+
+#define M_ASN1_I2D_put_SET_opt(a,f) \
+	if ((a != NULL) && (sk_num(a) != 0)) \
+		M_ASN1_I2D_put_SET(a,f);
+
+#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
+	if ((a != NULL) && (sk_num(a) != 0)) \
+		M_ASN1_I2D_put_SEQUENCE(a,f);
+
+#define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \
+	if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+		M_ASN1_I2D_put_SEQUENCE_type(type,a,f);
+
+#define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \
+	if ((c.slen != 0) && \
+		(M_ASN1_next == \
+		(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
+		{ \
+		M_ASN1_D2I_get_imp_set(b,func,free_func,\
+			tag,V_ASN1_CONTEXT_SPECIFIC); \
+		}
+
+#define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \
+	if ((c.slen != 0) && \
+		(M_ASN1_next == \
+		(V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\
+		{ \
+		M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\
+			tag,V_ASN1_CONTEXT_SPECIFIC); \
+		}
+
+#define M_ASN1_D2I_get_seq(r,func,free_func) \
+		M_ASN1_D2I_get_imp_set(r,func,free_func,\
+			V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
+
+#define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \
+		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
+					    V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
+
+#define M_ASN1_D2I_get_seq_opt(r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
+		{ M_ASN1_D2I_get_seq(r,func,free_func); }
+
+#define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \
+	if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \
+		V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\
+		{ M_ASN1_D2I_get_seq_type(type,r,func,free_func); }
+
+#define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \
+		M_ASN1_D2I_get_imp_set(r,func,free_func,\
+			x,V_ASN1_CONTEXT_SPECIFIC);
+
+#define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \
+		M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\
+			x,V_ASN1_CONTEXT_SPECIFIC);
+
+#define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \
+	c.q=c.p; \
+	if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\
+		(void (*)())free_func,a,b) == NULL) \
+		{ c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \
+	c.q=c.p; \
+	if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\
+				   free_func,a,b) == NULL) \
+		{ c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_set_strings(r,func,a,b) \
+	c.q=c.p; \
+	if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \
+		{ c.line=__LINE__; goto err; } \
+	c.slen-=(c.p-c.q);
+
+#define M_ASN1_D2I_get_EXP_opt(r,func,tag) \
+	if ((c.slen != 0L) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (func(&(r),&c.p,Tlen) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
+#define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \
+	if ((c.slen != 0) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \
+			(void (*)())free_func, \
+			b,V_ASN1_UNIVERSAL) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
+#define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \
+	if ((c.slen != 0) && (M_ASN1_next == \
+		(V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \
+		{ \
+		int Tinf,Ttag,Tclass; \
+		long Tlen; \
+		\
+		c.q=c.p; \
+		Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \
+		if (Tinf & 0x80) \
+			{ c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \
+			c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) \
+					Tlen = c.slen - (c.p - c.q) - 2; \
+		if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \
+			free_func,b,V_ASN1_UNIVERSAL) == NULL) \
+			{ c.line=__LINE__; goto err; } \
+		if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \
+			Tlen = c.slen - (c.p - c.q); \
+			if(!ASN1_check_infinite_end(&c.p, Tlen)) \
+				{ c.error=ERR_R_MISSING_ASN1_EOS; \
+				c.line=__LINE__; goto err; } \
+		}\
+		c.slen-=(c.p-c.q); \
+		}
+
+/* New macros */
+#define M_ASN1_New_Malloc(ret,type) \
+	if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \
+		{ c.line=__LINE__; goto err2; }
+
+#define M_ASN1_New(arg,func) \
+	if (((arg)=func()) == NULL) return(NULL)
+
+#define M_ASN1_New_Error(a) \
+/*	err:	ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \
+		return(NULL);*/ \
+	err2:	ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \
+		return(NULL)
+
+
+/* BIG UGLY WARNING!  This is so damn ugly I wanna puke.  Unfortunately,
+   some macros that use ASN1_const_CTX still insist on writing in the input
+   stream.  ARGH!  ARGH!  ARGH!  Let's get rid of this macro package.
+   Please?						-- Richard Levitte */
+#define M_ASN1_next		(*((unsigned char *)(c.p)))
+#define M_ASN1_next_prev	(*((unsigned char *)(c.q)))
+
+/*************************************************/
+
+#define M_ASN1_I2D_vars(a)	int r=0,ret=0; \
+				unsigned char *p; \
+				if (a == NULL) return(0)
+
+/* Length Macros */
+#define M_ASN1_I2D_len(a,f)	ret+=f(a,NULL)
+#define M_ASN1_I2D_len_IMP_opt(a,f)	if (a != NULL) M_ASN1_I2D_len(a,f)
+
+#define M_ASN1_I2D_len_SET(a,f) \
+		ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
+
+#define M_ASN1_I2D_len_SET_type(type,a,f) \
+		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \
+					    V_ASN1_UNIVERSAL,IS_SET);
+
+#define M_ASN1_I2D_len_SEQUENCE(a,f) \
+		ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+				  IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \
+		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \
+					    V_ASN1_UNIVERSAL,IS_SEQUENCE)
+
+#define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			M_ASN1_I2D_len_SEQUENCE(a,f);
+
+#define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			M_ASN1_I2D_len_SEQUENCE_type(type,a,f);
+
+#define M_ASN1_I2D_len_IMP_SET(a,f,x) \
+		ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \
+		ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+					    V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+					  IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+					       V_ASN1_CONTEXT_SPECIFIC,IS_SET);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \
+		ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+				  IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+					  IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \
+						    V_ASN1_CONTEXT_SPECIFIC, \
+						    IS_SEQUENCE);
+
+#define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \
+		if (a != NULL)\
+			{ \
+			v=f(a,NULL); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+#define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+#define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \
+				       IS_SEQUENCE); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+#define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0))\
+			{ \
+			v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \
+						 V_ASN1_UNIVERSAL, \
+						 IS_SEQUENCE); \
+			ret+=ASN1_object_size(1,v,mtag); \
+			}
+
+/* Put Macros */
+#define M_ASN1_I2D_put(a,f)	f(a,&p)
+
+#define M_ASN1_I2D_put_IMP_opt(a,f,t)	\
+		if (a != NULL) \
+			{ \
+			unsigned char *q=p; \
+			f(a,&p); \
+			*q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\
+			}
+
+#define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\
+			V_ASN1_UNIVERSAL,IS_SET)
+#define M_ASN1_I2D_put_SET_type(type,a,f) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET)
+#define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+			V_ASN1_CONTEXT_SPECIFIC,IS_SET)
+#define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET)
+#define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\
+			V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\
+					     V_ASN1_UNIVERSAL,IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \
+     i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \
+			    IS_SEQUENCE)
+
+#define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			M_ASN1_I2D_put_SEQUENCE(a,f);
+
+#define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+				       IS_SET); }
+
+#define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
+						 V_ASN1_CONTEXT_SPECIFIC, \
+						 IS_SET); }
+
+#define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \
+				       IS_SEQUENCE); }
+
+#define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ i2d_ASN1_SET_OF_##type(a,&p,f,x, \
+						 V_ASN1_CONTEXT_SPECIFIC, \
+						 IS_SEQUENCE); }
+
+#define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \
+		if (a != NULL) \
+			{ \
+			ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \
+			f(a,&p); \
+			}
+
+#define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \
+			}
+
+#define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \
+			}
+
+#define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \
+		if ((a != NULL) && (sk_##type##_num(a) != 0)) \
+			{ \
+			ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \
+			i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \
+					       IS_SEQUENCE); \
+			}
+
+#define M_ASN1_I2D_seq_total() \
+		r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \
+		if (pp == NULL) return(r); \
+		p= *pp; \
+		ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL)
+
+#define M_ASN1_I2D_INF_seq_start(tag,ctx) \
+		*(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \
+		*(p++)=0x80
+
+#define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00
+
+#define M_ASN1_I2D_finish()	*pp=p; \
+				return(r);
+
+int asn1_GetSequence(ASN1_const_CTX *c, long *length);
+void asn1_add_error(const unsigned char *address,int offset);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/asn1t.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/asn1t.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/asn1t.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,886 @@
+/* asn1t.h */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ASN1T_H
+#define HEADER_ASN1T_H
+
+#include <stddef.h>
+#include <openssl/e_os2.h>
+#include <openssl/asn1.h>
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+/* ASN1 template defines, structures and functions */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
+
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#define ASN1_ITEM_start(itname) \
+	OPENSSL_GLOBAL const ASN1_ITEM itname##_it = {
+
+#define ASN1_ITEM_end(itname) \
+		};
+
+#else
+
+/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
+#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr()))
+
+
+/* Macros for start and end of ASN1_ITEM definition */
+
+#define ASN1_ITEM_start(itname) \
+	const ASN1_ITEM * itname##_it(void) \
+	{ \
+		static const ASN1_ITEM local_it = { \
+
+#define ASN1_ITEM_end(itname) \
+		}; \
+	return &local_it; \
+	}
+
+#endif
+
+
+/* Macros to aid ASN1 template writing */
+
+#define ASN1_ITEM_TEMPLATE(tname) \
+	static const ASN1_TEMPLATE tname##_item_tt 
+
+#define ASN1_ITEM_TEMPLATE_END(tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_PRIMITIVE,\
+		-1,\
+		&tname##_item_tt,\
+		0,\
+		NULL,\
+		0,\
+		#tname \
+	ASN1_ITEM_end(tname)
+
+
+/* This is a ASN1 type which just embeds a template */
+ 
+/* This pair helps declare a SEQUENCE. We can do:
+ *
+ * 	ASN1_SEQUENCE(stname) = {
+ * 		... SEQUENCE components ...
+ * 	} ASN1_SEQUENCE_END(stname)
+ *
+ * 	This will produce an ASN1_ITEM called stname_it
+ *	for a structure called stname.
+ *
+ * 	If you want the same structure but a different
+ *	name then use:
+ *
+ * 	ASN1_SEQUENCE(itname) = {
+ * 		... SEQUENCE components ...
+ * 	} ASN1_SEQUENCE_END_name(stname, itname)
+ *
+ *	This will create an item called itname_it using
+ *	a structure called stname.
+ */
+
+#define ASN1_SEQUENCE(tname) \
+	static const ASN1_TEMPLATE tname##_seq_tt[] 
+
+#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
+
+#define ASN1_SEQUENCE_END_name(stname, tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		NULL,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_NDEF_SEQUENCE(tname) \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_SEQUENCE_cb(tname, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_BROKEN_SEQUENCE(tname) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_SEQUENCE_ref(tname, cb, lck) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_SEQUENCE_enc(tname, enc, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \
+	ASN1_SEQUENCE(tname)
+
+#define ASN1_NDEF_SEQUENCE_END(tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_NDEF_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		NULL,\
+		sizeof(tname),\
+		#tname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
+
+#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
+
+#define ASN1_SEQUENCE_END_ref(stname, tname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_SEQUENCE,\
+		V_ASN1_SEQUENCE,\
+		tname##_seq_tt,\
+		sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
+		&tname##_aux,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+
+/* This pair helps declare a CHOICE type. We can do:
+ *
+ * 	ASN1_CHOICE(chname) = {
+ * 		... CHOICE options ...
+ * 	ASN1_CHOICE_END(chname)
+ *
+ * 	This will produce an ASN1_ITEM called chname_it
+ *	for a structure called chname. The structure
+ *	definition must look like this:
+ *	typedef struct {
+ *		int type;
+ *		union {
+ *			ASN1_SOMETHING *opt1;
+ *			ASN1_SOMEOTHER *opt2;
+ *		} value;
+ *	} chname;
+ *	
+ *	the name of the selector must be 'type'.
+ * 	to use an alternative selector name use the
+ *      ASN1_CHOICE_END_selector() version.
+ */
+
+#define ASN1_CHOICE(tname) \
+	static const ASN1_TEMPLATE tname##_ch_tt[] 
+
+#define ASN1_CHOICE_cb(tname, cb) \
+	static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \
+	ASN1_CHOICE(tname)
+
+#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
+
+#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
+
+#define ASN1_CHOICE_END_selector(stname, tname, selname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_CHOICE,\
+		offsetof(stname,selname) ,\
+		tname##_ch_tt,\
+		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+		NULL,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+#define ASN1_CHOICE_END_cb(stname, tname, selname) \
+	;\
+	ASN1_ITEM_start(tname) \
+		ASN1_ITYPE_CHOICE,\
+		offsetof(stname,selname) ,\
+		tname##_ch_tt,\
+		sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
+		&tname##_aux,\
+		sizeof(stname),\
+		#stname \
+	ASN1_ITEM_end(tname)
+
+/* This helps with the template wrapper form of ASN1_ITEM */
+
+#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
+	(flags), (tag), 0,\
+	#name, ASN1_ITEM_ref(type) }
+
+/* These help with SEQUENCE or CHOICE components */
+
+/* used to declare other types */
+
+#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
+	(flags), (tag), offsetof(stname, field),\
+	#field, ASN1_ITEM_ref(type) }
+
+/* used when the structure is combined with the parent */
+
+#define ASN1_EX_COMBINE(flags, tag, type) { \
+	(flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
+
+/* implicit and explicit helper macros */
+
+#define ASN1_IMP_EX(stname, field, type, tag, ex) \
+		ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
+
+#define ASN1_EXP_EX(stname, field, type, tag, ex) \
+		ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
+
+/* Any defined by macros: the field used is in the table itself */
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
+#else
+#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb }
+#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb }
+#endif
+/* Plain simple type */
+#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
+
+/* OPTIONAL simple type */
+#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* IMPLICIT tagged simple type */
+#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
+
+/* IMPLICIT tagged OPTIONAL simple type */
+#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* Same as above but EXPLICIT */
+
+#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
+#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
+
+/* SEQUENCE OF type */
+#define ASN1_SEQUENCE_OF(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
+
+/* OPTIONAL SEQUENCE OF */
+#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Same as above but for SET OF */
+
+#define ASN1_SET_OF(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
+
+#define ASN1_SET_OF_OPT(stname, field, type) \
+		ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
+
+/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
+
+#define ASN1_IMP_SET_OF(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+#define ASN1_EXP_SET_OF(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
+
+#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+			ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
+
+#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
+
+/* EXPLICIT OPTIONAL using indefinite length constructed form */
+#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
+			ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
+
+/* Macros for the ASN1_ADB structure */
+
+#define ASN1_ADB(name) \
+	static const ASN1_ADB_TABLE name##_adbtbl[] 
+
+#ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+	;\
+	static const ASN1_ADB name##_adb = {\
+		flags,\
+		offsetof(name, field),\
+		app_table,\
+		name##_adbtbl,\
+		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+		def,\
+		none\
+	}
+
+#else
+
+#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
+	;\
+	static const ASN1_ITEM *name##_adb(void) \
+	{ \
+	static const ASN1_ADB internal_adb = \
+		{\
+		flags,\
+		offsetof(name, field),\
+		app_table,\
+		name##_adbtbl,\
+		sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
+		def,\
+		none\
+		}; \
+		return (const ASN1_ITEM *) &internal_adb; \
+	} \
+	void dummy_function(void)
+
+#endif
+
+#define ADB_ENTRY(val, template) {val, template}
+
+#define ASN1_ADB_TEMPLATE(name) \
+	static const ASN1_TEMPLATE name##_tt 
+
+/* This is the ASN1 template structure that defines
+ * a wrapper round the actual type. It determines the
+ * actual position of the field in the value structure,
+ * various flags such as OPTIONAL and the field name.
+ */
+
+struct ASN1_TEMPLATE_st {
+unsigned long flags;		/* Various flags */
+long tag;			/* tag, not used if no tagging */
+unsigned long offset;		/* Offset of this field in structure */
+#ifndef NO_ASN1_FIELD_NAMES
+const char *field_name;		/* Field name */
+#endif
+ASN1_ITEM_EXP *item;		/* Relevant ASN1_ITEM or ASN1_ADB */
+};
+
+/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
+
+#define ASN1_TEMPLATE_item(t) (t->item_ptr)
+#define ASN1_TEMPLATE_adb(t) (t->item_ptr)
+
+typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
+typedef struct ASN1_ADB_st ASN1_ADB;
+
+struct ASN1_ADB_st {
+	unsigned long flags;	/* Various flags */
+	unsigned long offset;	/* Offset of selector field */
+	STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
+	const ASN1_ADB_TABLE *tbl;	/* Table of possible types */
+	long tblcount;		/* Number of entries in tbl */
+	const ASN1_TEMPLATE *default_tt;  /* Type to use if no match */
+	const ASN1_TEMPLATE *null_tt;  /* Type to use if selector is NULL */
+};
+
+struct ASN1_ADB_TABLE_st {
+	long value;		/* NID for an object or value for an int */
+	const ASN1_TEMPLATE tt;		/* item for this value */
+};
+
+/* template flags */
+
+/* Field is optional */
+#define ASN1_TFLG_OPTIONAL	(0x1)
+
+/* Field is a SET OF */
+#define ASN1_TFLG_SET_OF	(0x1 << 1)
+
+/* Field is a SEQUENCE OF */
+#define ASN1_TFLG_SEQUENCE_OF	(0x2 << 1)
+
+/* Special case: this refers to a SET OF that
+ * will be sorted into DER order when encoded *and*
+ * the corresponding STACK will be modified to match
+ * the new order.
+ */
+#define ASN1_TFLG_SET_ORDER	(0x3 << 1)
+
+/* Mask for SET OF or SEQUENCE OF */
+#define ASN1_TFLG_SK_MASK	(0x3 << 1)
+
+/* These flags mean the tag should be taken from the
+ * tag field. If EXPLICIT then the underlying type
+ * is used for the inner tag.
+ */
+
+/* IMPLICIT tagging */
+#define ASN1_TFLG_IMPTAG	(0x1 << 3)
+
+
+/* EXPLICIT tagging, inner tag from underlying type */
+#define ASN1_TFLG_EXPTAG	(0x2 << 3)
+
+#define ASN1_TFLG_TAG_MASK	(0x3 << 3)
+
+/* context specific IMPLICIT */
+#define ASN1_TFLG_IMPLICIT	ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
+
+/* context specific EXPLICIT */
+#define ASN1_TFLG_EXPLICIT	ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
+
+/* If tagging is in force these determine the
+ * type of tag to use. Otherwise the tag is
+ * determined by the underlying type. These 
+ * values reflect the actual octet format.
+ */
+
+/* Universal tag */ 
+#define ASN1_TFLG_UNIVERSAL	(0x0<<6)
+/* Application tag */ 
+#define ASN1_TFLG_APPLICATION	(0x1<<6)
+/* Context specific tag */ 
+#define ASN1_TFLG_CONTEXT	(0x2<<6)
+/* Private tag */ 
+#define ASN1_TFLG_PRIVATE	(0x3<<6)
+
+#define ASN1_TFLG_TAG_CLASS	(0x3<<6)
+
+/* These are for ANY DEFINED BY type. In this case
+ * the 'item' field points to an ASN1_ADB structure
+ * which contains a table of values to decode the
+ * relevant type
+ */
+
+#define ASN1_TFLG_ADB_MASK	(0x3<<8)
+
+#define ASN1_TFLG_ADB_OID	(0x1<<8)
+
+#define ASN1_TFLG_ADB_INT	(0x1<<9)
+
+/* This flag means a parent structure is passed
+ * instead of the field: this is useful is a
+ * SEQUENCE is being combined with a CHOICE for
+ * example. Since this means the structure and
+ * item name will differ we need to use the
+ * ASN1_CHOICE_END_name() macro for example.
+ */
+
+#define ASN1_TFLG_COMBINE	(0x1<<10)
+
+/* This flag when present in a SEQUENCE OF, SET OF
+ * or EXPLICIT causes indefinite length constructed
+ * encoding to be used if required.
+ */
+
+#define ASN1_TFLG_NDEF		(0x1<<11)
+
+/* This is the actual ASN1 item itself */
+
+struct ASN1_ITEM_st {
+char itype;			/* The item type, primitive, SEQUENCE, CHOICE or extern */
+long utype;			/* underlying type */
+const ASN1_TEMPLATE *templates;	/* If SEQUENCE or CHOICE this contains the contents */
+long tcount;			/* Number of templates if SEQUENCE or CHOICE */
+const void *funcs;		/* functions that handle this type */
+long size;			/* Structure size (usually)*/
+#ifndef NO_ASN1_FIELD_NAMES
+const char *sname;		/* Structure name */
+#endif
+};
+
+/* These are values for the itype field and
+ * determine how the type is interpreted.
+ *
+ * For PRIMITIVE types the underlying type
+ * determines the behaviour if items is NULL.
+ *
+ * Otherwise templates must contain a single 
+ * template and the type is treated in the
+ * same way as the type specified in the template.
+ *
+ * For SEQUENCE types the templates field points
+ * to the members, the size field is the
+ * structure size.
+ *
+ * For CHOICE types the templates field points
+ * to each possible member (typically a union)
+ * and the 'size' field is the offset of the
+ * selector.
+ *
+ * The 'funcs' field is used for application
+ * specific functions. 
+ *
+ * For COMPAT types the funcs field gives a
+ * set of functions that handle this type, this
+ * supports the old d2i, i2d convention.
+ *
+ * The EXTERN type uses a new style d2i/i2d.
+ * The new style should be used where possible
+ * because it avoids things like the d2i IMPLICIT
+ * hack.
+ *
+ * MSTRING is a multiple string type, it is used
+ * for a CHOICE of character strings where the
+ * actual strings all occupy an ASN1_STRING
+ * structure. In this case the 'utype' field
+ * has a special meaning, it is used as a mask
+ * of acceptable types using the B_ASN1 constants.
+ *
+ * NDEF_SEQUENCE is the same as SEQUENCE except
+ * that it will use indefinite length constructed
+ * encoding if requested.
+ *
+ */
+
+#define ASN1_ITYPE_PRIMITIVE		0x0
+
+#define ASN1_ITYPE_SEQUENCE		0x1
+
+#define ASN1_ITYPE_CHOICE		0x2
+
+#define ASN1_ITYPE_COMPAT		0x3
+
+#define ASN1_ITYPE_EXTERN		0x4
+
+#define ASN1_ITYPE_MSTRING		0x5
+
+#define ASN1_ITYPE_NDEF_SEQUENCE	0x6
+
+/* Cache for ASN1 tag and length, so we
+ * don't keep re-reading it for things
+ * like CHOICE
+ */
+
+struct ASN1_TLC_st{
+	char valid;	/* Values below are valid */
+	int ret;	/* return value */
+	long plen;	/* length */
+	int ptag;	/* class value */
+	int pclass;	/* class value */
+	int hdrlen;	/* header length */
+};
+
+/* Typedefs for ASN1 function pointers */
+
+typedef ASN1_VALUE * ASN1_new_func(void);
+typedef void ASN1_free_func(ASN1_VALUE *a);
+typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length);
+typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in);
+
+typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
+					int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
+typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+
+typedef struct ASN1_COMPAT_FUNCS_st {
+	ASN1_new_func *asn1_new;
+	ASN1_free_func *asn1_free;
+	ASN1_d2i_func *asn1_d2i;
+	ASN1_i2d_func *asn1_i2d;
+} ASN1_COMPAT_FUNCS;
+
+typedef struct ASN1_EXTERN_FUNCS_st {
+	void *app_data;
+	ASN1_ex_new_func *asn1_ex_new;
+	ASN1_ex_free_func *asn1_ex_free;
+	ASN1_ex_free_func *asn1_ex_clear;
+	ASN1_ex_d2i *asn1_ex_d2i;
+	ASN1_ex_i2d *asn1_ex_i2d;
+} ASN1_EXTERN_FUNCS;
+
+typedef struct ASN1_PRIMITIVE_FUNCS_st {
+	void *app_data;
+	unsigned long flags;
+	ASN1_ex_new_func *prim_new;
+	ASN1_ex_free_func *prim_free;
+	ASN1_ex_free_func *prim_clear;
+	ASN1_primitive_c2i *prim_c2i;
+	ASN1_primitive_i2c *prim_i2c;
+} ASN1_PRIMITIVE_FUNCS;
+
+/* This is the ASN1_AUX structure: it handles various
+ * miscellaneous requirements. For example the use of
+ * reference counts and an informational callback.
+ *
+ * The "informational callback" is called at various
+ * points during the ASN1 encoding and decoding. It can
+ * be used to provide minor customisation of the structures
+ * used. This is most useful where the supplied routines
+ * *almost* do the right thing but need some extra help
+ * at a few points. If the callback returns zero then
+ * it is assumed a fatal error has occurred and the 
+ * main operation should be abandoned.
+ *
+ * If major changes in the default behaviour are required
+ * then an external type is more appropriate.
+ */
+
+typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it);
+
+typedef struct ASN1_AUX_st {
+	void *app_data;
+	int flags;
+	int ref_offset;		/* Offset of reference value */
+	int ref_lock;		/* Lock type to use */
+	ASN1_aux_cb *asn1_cb;
+	int enc_offset;		/* Offset of ASN1_ENCODING structure */
+} ASN1_AUX;
+
+/* Flags in ASN1_AUX */
+
+/* Use a reference count */
+#define ASN1_AFLG_REFCOUNT	1
+/* Save the encoding of structure (useful for signatures) */
+#define ASN1_AFLG_ENCODING	2
+/* The Sequence length is invalid */
+#define ASN1_AFLG_BROKEN	4
+
+/* operation values for asn1_cb */
+
+#define ASN1_OP_NEW_PRE		0
+#define ASN1_OP_NEW_POST	1
+#define ASN1_OP_FREE_PRE	2
+#define ASN1_OP_FREE_POST	3
+#define ASN1_OP_D2I_PRE		4
+#define ASN1_OP_D2I_POST	5
+#define ASN1_OP_I2D_PRE		6
+#define ASN1_OP_I2D_POST	7
+
+/* Macro to implement a primitive type */
+#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
+#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
+				ASN1_ITEM_start(itname) \
+					ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
+				ASN1_ITEM_end(itname)
+
+/* Macro to implement a multi string type */
+#define IMPLEMENT_ASN1_MSTRING(itname, mask) \
+				ASN1_ITEM_start(itname) \
+					ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
+				ASN1_ITEM_end(itname)
+
+/* Macro to implement an ASN1_ITEM in terms of old style funcs */
+
+#define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
+
+#define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
+	static const ASN1_COMPAT_FUNCS sname##_ff = { \
+		(ASN1_new_func *)sname##_new, \
+		(ASN1_free_func *)sname##_free, \
+		(ASN1_d2i_func *)d2i_##sname, \
+		(ASN1_i2d_func *)i2d_##sname, \
+	}; \
+	ASN1_ITEM_start(sname) \
+		ASN1_ITYPE_COMPAT, \
+		tag, \
+		NULL, \
+		0, \
+		&sname##_ff, \
+		0, \
+		#sname \
+	ASN1_ITEM_end(sname)
+
+#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
+	ASN1_ITEM_start(sname) \
+		ASN1_ITYPE_EXTERN, \
+		tag, \
+		NULL, \
+		0, \
+		&fptrs, \
+		0, \
+		#sname \
+	ASN1_ITEM_end(sname)
+
+/* Macro to implement standard functions in terms of ASN1_ITEM structures */
+
+#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
+
+#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
+
+#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
+			IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
+
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
+		IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
+
+#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
+	stname *fname##_new(void) \
+	{ \
+		return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
+	} \
+	void fname##_free(stname *a) \
+	{ \
+		ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
+	}
+
+#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
+	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+	{ \
+		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+	} \
+	int i2d_##fname(stname *a, unsigned char **out) \
+	{ \
+		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+	} 
+
+#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
+	int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
+	{ \
+		return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
+	} 
+
+/* This includes evil casts to remove const: they will go away when full
+ * ASN1 constification is done.
+ */
+#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+	stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
+	{ \
+		return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
+	} \
+	int i2d_##fname(const stname *a, unsigned char **out) \
+	{ \
+		return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
+	} 
+
+#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
+	stname * stname##_dup(stname *x) \
+        { \
+        return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
+        }
+
+#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
+		IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
+
+#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
+	IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
+
+/* external definitions for primitive types */
+
+DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
+DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
+DECLARE_ASN1_ITEM(CBIGNUM)
+DECLARE_ASN1_ITEM(BIGNUM)
+DECLARE_ASN1_ITEM(LONG)
+DECLARE_ASN1_ITEM(ZLONG)
+
+DECLARE_STACK_OF(ASN1_VALUE)
+
+/* Functions used internally by the ASN1 code */
+
+int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt);
+int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
+				int tag, int aclass, char opt, ASN1_TLC *ctx);
+
+int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
+int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt);
+void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+
+int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
+int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
+
+int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
+
+ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
+
+const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
+
+int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+
+void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
+void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/bio.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/bio.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/bio.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,767 @@
+/* crypto/bio/bio.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BIO_H
+#define HEADER_BIO_H
+
+#include <openssl/e_os2.h>
+
+#ifndef OPENSSL_NO_FP_API
+# include <stdio.h>
+#endif
+#include <stdarg.h>
+
+#include <openssl/crypto.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* These are the 'types' of BIOs */
+#define BIO_TYPE_NONE		0
+#define BIO_TYPE_MEM		(1|0x0400)
+#define BIO_TYPE_FILE		(2|0x0400)
+
+#define BIO_TYPE_FD		(4|0x0400|0x0100)
+#define BIO_TYPE_SOCKET		(5|0x0400|0x0100)
+#define BIO_TYPE_NULL		(6|0x0400)
+#define BIO_TYPE_SSL		(7|0x0200)
+#define BIO_TYPE_MD		(8|0x0200)		/* passive filter */
+#define BIO_TYPE_BUFFER		(9|0x0200)		/* filter */
+#define BIO_TYPE_CIPHER		(10|0x0200)		/* filter */
+#define BIO_TYPE_BASE64		(11|0x0200)		/* filter */
+#define BIO_TYPE_CONNECT	(12|0x0400|0x0100)	/* socket - connect */
+#define BIO_TYPE_ACCEPT		(13|0x0400|0x0100)	/* socket for accept */
+#define BIO_TYPE_PROXY_CLIENT	(14|0x0200)		/* client proxy BIO */
+#define BIO_TYPE_PROXY_SERVER	(15|0x0200)		/* server proxy BIO */
+#define BIO_TYPE_NBIO_TEST	(16|0x0200)		/* server proxy BIO */
+#define BIO_TYPE_NULL_FILTER	(17|0x0200)
+#define BIO_TYPE_BER		(18|0x0200)		/* BER -> bin filter */
+#define BIO_TYPE_BIO		(19|0x0400)		/* (half a) BIO pair */
+#define BIO_TYPE_LINEBUFFER	(20|0x0200)		/* filter */
+#define BIO_TYPE_DGRAM		(21|0x0400|0x0100)
+
+#define BIO_TYPE_DESCRIPTOR	0x0100	/* socket, fd, connect or accept */
+#define BIO_TYPE_FILTER		0x0200
+#define BIO_TYPE_SOURCE_SINK	0x0400
+
+/* BIO_FILENAME_READ|BIO_CLOSE to open or close on free.
+ * BIO_set_fp(in,stdin,BIO_NOCLOSE); */
+#define BIO_NOCLOSE		0x00
+#define BIO_CLOSE		0x01
+
+/* These are used in the following macros and are passed to
+ * BIO_ctrl() */
+#define BIO_CTRL_RESET		1  /* opt - rewind/zero etc */
+#define BIO_CTRL_EOF		2  /* opt - are we at the eof */
+#define BIO_CTRL_INFO		3  /* opt - extra tit-bits */
+#define BIO_CTRL_SET		4  /* man - set the 'IO' type */
+#define BIO_CTRL_GET		5  /* man - get the 'IO' type */
+#define BIO_CTRL_PUSH		6  /* opt - internal, used to signify change */
+#define BIO_CTRL_POP		7  /* opt - internal, used to signify change */
+#define BIO_CTRL_GET_CLOSE	8  /* man - set the 'close' on free */
+#define BIO_CTRL_SET_CLOSE	9  /* man - set the 'close' on free */
+#define BIO_CTRL_PENDING	10  /* opt - is their more data buffered */
+#define BIO_CTRL_FLUSH		11  /* opt - 'flush' buffered output */
+#define BIO_CTRL_DUP		12  /* man - extra stuff for 'duped' BIO */
+#define BIO_CTRL_WPENDING	13  /* opt - number of bytes still to write */
+/* callback is int cb(BIO *bio,state,ret); */
+#define BIO_CTRL_SET_CALLBACK	14  /* opt - set callback function */
+#define BIO_CTRL_GET_CALLBACK	15  /* opt - set callback function */
+
+#define BIO_CTRL_SET_FILENAME	30	/* BIO_s_file special */
+
+/* dgram BIO stuff */
+#define BIO_CTRL_DGRAM_CONNECT       31  /* BIO dgram special */
+#define BIO_CTRL_DGRAM_SET_CONNECTED 32  /* allow for an externally
+										  * connected socket to be
+										  * passed in */ 
+#define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33 /* setsockopt, essentially */
+#define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34 /* getsockopt, essentially */
+#define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35 /* setsockopt, essentially */
+#define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36 /* getsockopt, essentially */
+
+#define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37 /* flag whether the last */
+#define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38 /* I/O operation tiemd out */
+					
+/* #ifdef IP_MTU_DISCOVER */
+#define BIO_CTRL_DGRAM_MTU_DISCOVER       39 /* set DF bit on egress packets */
+/* #endif */
+
+#define BIO_CTRL_DGRAM_QUERY_MTU          40 /* as kernel for current MTU */
+#define BIO_CTRL_DGRAM_GET_MTU            41 /* get cached value for MTU */
+#define BIO_CTRL_DGRAM_SET_MTU            42 /* set cached value for
+											  * MTU. want to use this
+                                              * if asking the kernel
+                                              * fails */
+
+#define BIO_CTRL_DGRAM_MTU_EXCEEDED       43 /* check whether the MTU
+											  * was exceed in the
+											  * previous write
+											  * operation */
+
+#define BIO_CTRL_DGRAM_SET_PEER           44 /* Destination for the data */
+
+
+/* modifiers */
+#define BIO_FP_READ		0x02
+#define BIO_FP_WRITE		0x04
+#define BIO_FP_APPEND		0x08
+#define BIO_FP_TEXT		0x10
+
+#define BIO_FLAGS_READ		0x01
+#define BIO_FLAGS_WRITE		0x02
+#define BIO_FLAGS_IO_SPECIAL	0x04
+#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
+#define BIO_FLAGS_SHOULD_RETRY	0x08
+#ifndef	BIO_FLAGS_UPLINK
+/* "UPLINK" flag denotes file descriptors provided by application.
+   It defaults to 0, as most platforms don't require UPLINK interface. */
+#define	BIO_FLAGS_UPLINK	0
+#endif
+
+/* Used in BIO_gethostbyname() */
+#define BIO_GHBN_CTRL_HITS		1
+#define BIO_GHBN_CTRL_MISSES		2
+#define BIO_GHBN_CTRL_CACHE_SIZE	3
+#define BIO_GHBN_CTRL_GET_ENTRY		4
+#define BIO_GHBN_CTRL_FLUSH		5
+
+/* Mostly used in the SSL BIO */
+/* Not used anymore
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10
+ * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20
+ * #define BIO_FLAGS_PROTOCOL_STARTUP	0x40
+ */
+
+#define BIO_FLAGS_BASE64_NO_NL	0x100
+
+/* This is used with memory BIOs: it means we shouldn't free up or change the
+ * data in any way.
+ */
+#define BIO_FLAGS_MEM_RDONLY	0x200
+
+#define BIO_set_flags(b,f) ((b)->flags|=(f))
+#define BIO_get_flags(b) ((b)->flags)
+#define BIO_set_retry_special(b) \
+		((b)->flags|=(BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_read(b) \
+		((b)->flags|=(BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_set_retry_write(b) \
+		((b)->flags|=(BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY))
+
+/* These are normally used internally in BIOs */
+#define BIO_clear_flags(b,f) ((b)->flags&= ~(f))
+#define BIO_clear_retry_flags(b) \
+		((b)->flags&= ~(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+#define BIO_get_retry_flags(b) \
+		((b)->flags&(BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY))
+
+/* These should be used by the application to tell why we should retry */
+#define BIO_should_read(a)		((a)->flags & BIO_FLAGS_READ)
+#define BIO_should_write(a)		((a)->flags & BIO_FLAGS_WRITE)
+#define BIO_should_io_special(a)	((a)->flags & BIO_FLAGS_IO_SPECIAL)
+#define BIO_retry_type(a)		((a)->flags & BIO_FLAGS_RWS)
+#define BIO_should_retry(a)		((a)->flags & BIO_FLAGS_SHOULD_RETRY)
+
+/* The next three are used in conjunction with the
+ * BIO_should_io_special() condition.  After this returns true,
+ * BIO *BIO_get_retry_BIO(BIO *bio, int *reason); will walk the BIO 
+ * stack and return the 'reason' for the special and the offending BIO.
+ * Given a BIO, BIO_get_retry_reason(bio) will return the code. */
+/* Returned from the SSL bio when the certificate retrieval code had an error */
+#define BIO_RR_SSL_X509_LOOKUP		0x01
+/* Returned from the connect BIO when a connect would have blocked */
+#define BIO_RR_CONNECT			0x02
+/* Returned from the accept BIO when an accept would have blocked */
+#define BIO_RR_ACCEPT			0x03
+
+/* These are passed by the BIO callback */
+#define BIO_CB_FREE	0x01
+#define BIO_CB_READ	0x02
+#define BIO_CB_WRITE	0x03
+#define BIO_CB_PUTS	0x04
+#define BIO_CB_GETS	0x05
+#define BIO_CB_CTRL	0x06
+
+/* The callback is called before and after the underling operation,
+ * The BIO_CB_RETURN flag indicates if it is after the call */
+#define BIO_CB_RETURN	0x80
+#define BIO_CB_return(a) ((a)|BIO_CB_RETURN))
+#define BIO_cb_pre(a)	(!((a)&BIO_CB_RETURN))
+#define BIO_cb_post(a)	((a)&BIO_CB_RETURN)
+
+#define BIO_set_callback(b,cb)		((b)->callback=(cb))
+#define BIO_set_callback_arg(b,arg)	((b)->cb_arg=(char *)(arg))
+#define BIO_get_callback_arg(b)		((b)->cb_arg)
+#define BIO_get_callback(b)		((b)->callback)
+#define BIO_method_name(b)		((b)->method->name)
+#define BIO_method_type(b)		((b)->method->type)
+
+typedef struct bio_st BIO;
+
+typedef void bio_info_cb(struct bio_st *, int, const char *, int, long, long);
+
+#ifndef OPENSSL_SYS_WIN16
+typedef struct bio_method_st
+	{
+	int type;
+	const char *name;
+	int (*bwrite)(BIO *, const char *, int);
+	int (*bread)(BIO *, char *, int);
+	int (*bputs)(BIO *, const char *);
+	int (*bgets)(BIO *, char *, int);
+	long (*ctrl)(BIO *, int, long, void *);
+	int (*create)(BIO *);
+	int (*destroy)(BIO *);
+        long (*callback_ctrl)(BIO *, int, bio_info_cb *);
+	} BIO_METHOD;
+#else
+typedef struct bio_method_st
+	{
+	int type;
+	const char *name;
+	int (_far *bwrite)();
+	int (_far *bread)();
+	int (_far *bputs)();
+	int (_far *bgets)();
+	long (_far *ctrl)();
+	int (_far *create)();
+	int (_far *destroy)();
+	long (_far *callback_ctrl)();
+	} BIO_METHOD;
+#endif
+
+struct bio_st
+	{
+	BIO_METHOD *method;
+	/* bio, mode, argp, argi, argl, ret */
+	long (*callback)(struct bio_st *,int,const char *,int, long,long);
+	char *cb_arg; /* first argument for the callback */
+
+	int init;
+	int shutdown;
+	int flags;	/* extra storage */
+	int retry_reason;
+	int num;
+	void *ptr;
+	struct bio_st *next_bio;	/* used by filter BIOs */
+	struct bio_st *prev_bio;	/* used by filter BIOs */
+	int references;
+	unsigned long num_read;
+	unsigned long num_write;
+
+	CRYPTO_EX_DATA ex_data;
+	};
+
+DECLARE_STACK_OF(BIO)
+
+typedef struct bio_f_buffer_ctx_struct
+	{
+	/* BIO *bio; */ /* this is now in the BIO struct */
+	int ibuf_size;	/* how big is the input buffer */
+	int obuf_size;	/* how big is the output buffer */
+
+	char *ibuf;		/* the char array */
+	int ibuf_len;		/* how many bytes are in it */
+	int ibuf_off;		/* write/read offset */
+
+	char *obuf;		/* the char array */
+	int obuf_len;		/* how many bytes are in it */
+	int obuf_off;		/* write/read offset */
+	} BIO_F_BUFFER_CTX;
+
+/* connect BIO stuff */
+#define BIO_CONN_S_BEFORE		1
+#define BIO_CONN_S_GET_IP		2
+#define BIO_CONN_S_GET_PORT		3
+#define BIO_CONN_S_CREATE_SOCKET	4
+#define BIO_CONN_S_CONNECT		5
+#define BIO_CONN_S_OK			6
+#define BIO_CONN_S_BLOCKED_CONNECT	7
+#define BIO_CONN_S_NBIO			8
+/*#define BIO_CONN_get_param_hostname	BIO_ctrl */
+
+#define BIO_C_SET_CONNECT			100
+#define BIO_C_DO_STATE_MACHINE			101
+#define BIO_C_SET_NBIO				102
+#define BIO_C_SET_PROXY_PARAM			103
+#define BIO_C_SET_FD				104
+#define BIO_C_GET_FD				105
+#define BIO_C_SET_FILE_PTR			106
+#define BIO_C_GET_FILE_PTR			107
+#define BIO_C_SET_FILENAME			108
+#define BIO_C_SET_SSL				109
+#define BIO_C_GET_SSL				110
+#define BIO_C_SET_MD				111
+#define BIO_C_GET_MD				112
+#define BIO_C_GET_CIPHER_STATUS			113
+#define BIO_C_SET_BUF_MEM			114
+#define BIO_C_GET_BUF_MEM_PTR			115
+#define BIO_C_GET_BUFF_NUM_LINES		116
+#define BIO_C_SET_BUFF_SIZE			117
+#define BIO_C_SET_ACCEPT			118
+#define BIO_C_SSL_MODE				119
+#define BIO_C_GET_MD_CTX			120
+#define BIO_C_GET_PROXY_PARAM			121
+#define BIO_C_SET_BUFF_READ_DATA		122 /* data to read first */
+#define BIO_C_GET_CONNECT			123
+#define BIO_C_GET_ACCEPT			124
+#define BIO_C_SET_SSL_RENEGOTIATE_BYTES		125
+#define BIO_C_GET_SSL_NUM_RENEGOTIATES		126
+#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT	127
+#define BIO_C_FILE_SEEK				128
+#define BIO_C_GET_CIPHER_CTX			129
+#define BIO_C_SET_BUF_MEM_EOF_RETURN		130/*return end of input value*/
+#define BIO_C_SET_BIND_MODE			131
+#define BIO_C_GET_BIND_MODE			132
+#define BIO_C_FILE_TELL				133
+#define BIO_C_GET_SOCKS				134
+#define BIO_C_SET_SOCKS				135
+
+#define BIO_C_SET_WRITE_BUF_SIZE		136/* for BIO_s_bio */
+#define BIO_C_GET_WRITE_BUF_SIZE		137
+#define BIO_C_MAKE_BIO_PAIR			138
+#define BIO_C_DESTROY_BIO_PAIR			139
+#define BIO_C_GET_WRITE_GUARANTEE		140
+#define BIO_C_GET_READ_REQUEST			141
+#define BIO_C_SHUTDOWN_WR			142
+#define BIO_C_NREAD0				143
+#define BIO_C_NREAD				144
+#define BIO_C_NWRITE0				145
+#define BIO_C_NWRITE				146
+#define BIO_C_RESET_READ_REQUEST		147
+
+
+#define BIO_set_app_data(s,arg)		BIO_set_ex_data(s,0,arg)
+#define BIO_get_app_data(s)		BIO_get_ex_data(s,0)
+
+/* BIO_s_connect() and BIO_s_socks4a_connect() */
+#define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name)
+#define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port)
+#define BIO_set_conn_ip(b,ip)	  BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip)
+#define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port)
+#define BIO_get_conn_hostname(b)  BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0)
+#define BIO_get_conn_port(b)      BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1)
+#define BIO_get_conn_ip(b) 		 BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2)
+#define BIO_get_conn_int_port(b) BIO_int_ctrl(b,BIO_C_GET_CONNECT,3)
+
+
+#define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL)
+
+/* BIO_s_accept_socket() */
+#define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name)
+#define BIO_get_accept_port(b)	BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0)
+/* #define BIO_set_nbio(b,n)	BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */
+#define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?"a":NULL)
+#define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio)
+
+#define BIO_BIND_NORMAL			0
+#define BIO_BIND_REUSEADDR_IF_UNUSED	1
+#define BIO_BIND_REUSEADDR		2
+#define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL)
+#define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL)
+
+#define BIO_do_connect(b)	BIO_do_handshake(b)
+#define BIO_do_accept(b)	BIO_do_handshake(b)
+#define BIO_do_handshake(b)	BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL)
+
+/* BIO_s_proxy_client() */
+#define BIO_set_url(b,url)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url))
+#define BIO_set_proxies(b,p)	BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p))
+/* BIO_set_nbio(b,n) */
+#define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s))
+/* BIO *BIO_get_filter_bio(BIO *bio); */
+#define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)()))
+#define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk)
+#define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool)
+
+#define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp)
+#define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p))
+#define BIO_get_url(b,url)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url))
+#define BIO_get_no_connect_return(b)	BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL)
+
+#define BIO_set_fd(b,fd,c)	BIO_int_ctrl(b,BIO_C_SET_FD,c,fd)
+#define BIO_get_fd(b,c)		BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c)
+
+#define BIO_set_fp(b,fp,c)	BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp)
+#define BIO_get_fp(b,fpp)	BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp)
+
+#define BIO_seek(b,ofs)	(int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL)
+#define BIO_tell(b)	(int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL)
+
+/* name is cast to lose const, but might be better to route through a function
+   so we can do it safely */
+#ifdef CONST_STRICT
+/* If you are wondering why this isn't defined, its because CONST_STRICT is
+ * purely a compile-time kludge to allow const to be checked.
+ */
+int BIO_read_filename(BIO *b,const char *name);
+#else
+#define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_READ,(char *)name)
+#endif
+#define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_WRITE,name)
+#define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_APPEND,name)
+#define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \
+		BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name)
+
+/* WARNING WARNING, this ups the reference count on the read bio of the
+ * SSL structure.  This is because the ssl read BIO is now pointed to by
+ * the next_bio field in the bio.  So when you free the BIO, make sure
+ * you are doing a BIO_free_all() to catch the underlying BIO. */
+#define BIO_set_ssl(b,ssl,c)	BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl)
+#define BIO_get_ssl(b,sslp)	BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
+#define BIO_set_ssl_mode(b,client)	BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
+#define BIO_set_ssl_renegotiate_bytes(b,num) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
+#define BIO_get_num_renegotiates(b) \
+	BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL);
+#define BIO_set_ssl_renegotiate_timeout(b,seconds) \
+	BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
+
+/* defined in evp.h */
+/* #define BIO_set_md(b,md)	BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
+
+#define BIO_get_mem_data(b,pp)	BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
+#define BIO_set_mem_buf(b,bm,c)	BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm)
+#define BIO_get_mem_ptr(b,pp)	BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp)
+#define BIO_set_mem_eof_return(b,v) \
+				BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL)
+
+/* For the BIO_f_buffer() type */
+#define BIO_get_buffer_num_lines(b)	BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL)
+#define BIO_set_buffer_size(b,size)	BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL)
+#define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0)
+#define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1)
+#define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf)
+
+/* Don't use the next one unless you know what you are doing :-) */
+#define BIO_dup_state(b,ret)	BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret))
+
+#define BIO_reset(b)		(int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL)
+#define BIO_eof(b)		(int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL)
+#define BIO_set_close(b,c)	(int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL)
+#define BIO_get_close(b)	(int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL)
+#define BIO_pending(b)		(int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
+#define BIO_wpending(b)		(int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL)
+/* ...pending macros have inappropriate return type */
+size_t BIO_ctrl_pending(BIO *b);
+size_t BIO_ctrl_wpending(BIO *b);
+#define BIO_flush(b)		(int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL)
+#define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \
+						   cbp)
+#define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb)
+
+/* For the BIO_f_buffer() type */
+#define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL)
+
+/* For BIO_s_bio() */
+#define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL)
+#define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL)
+#define BIO_make_bio_pair(b1,b2)   (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2)
+#define BIO_destroy_bio_pair(b)    (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL)
+#define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL)
+/* macros with inappropriate type -- but ...pending macros use int too: */
+#define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL)
+#define BIO_get_read_request(b)    (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL)
+size_t BIO_ctrl_get_write_guarantee(BIO *b);
+size_t BIO_ctrl_get_read_request(BIO *b);
+int BIO_ctrl_reset_read_request(BIO *b);
+
+/* ctrl macros for dgram */
+#define BIO_ctrl_dgram_connect(b,peer)  \
+                     (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer)
+#define BIO_ctrl_set_connected(b, state, peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer)
+#define BIO_dgram_recv_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL)
+#define BIO_dgram_send_timedout(b) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL)
+#define BIO_dgram_set_peer(b,peer) \
+         (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer)
+
+/* These two aren't currently implemented */
+/* int BIO_get_ex_num(BIO *bio); */
+/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */
+int BIO_set_ex_data(BIO *bio,int idx,void *data);
+void *BIO_get_ex_data(BIO *bio,int idx);
+int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+unsigned long BIO_number_read(BIO *bio);
+unsigned long BIO_number_written(BIO *bio);
+
+# ifndef OPENSSL_NO_FP_API
+#  if defined(OPENSSL_SYS_WIN16) && defined(_WINDLL)
+BIO_METHOD *BIO_s_file_internal(void);
+BIO *BIO_new_file_internal(char *filename, char *mode);
+BIO *BIO_new_fp_internal(FILE *stream, int close_flag);
+#    define BIO_s_file	BIO_s_file_internal
+#    define BIO_new_file	BIO_new_file_internal
+#    define BIO_new_fp	BIO_new_fp_internal
+#  else /* FP_API */
+BIO_METHOD *BIO_s_file(void );
+BIO *BIO_new_file(const char *filename, const char *mode);
+BIO *BIO_new_fp(FILE *stream, int close_flag);
+#    define BIO_s_file_internal		BIO_s_file
+#    define BIO_new_file_internal	BIO_new_file
+#    define BIO_new_fp_internal		BIO_s_file
+#  endif /* FP_API */
+# endif
+BIO *	BIO_new(BIO_METHOD *type);
+int	BIO_set(BIO *a,BIO_METHOD *type);
+int	BIO_free(BIO *a);
+void	BIO_vfree(BIO *a);
+int	BIO_read(BIO *b, void *data, int len);
+int	BIO_gets(BIO *bp,char *buf, int size);
+int	BIO_write(BIO *b, const void *data, int len);
+int	BIO_puts(BIO *bp,const char *buf);
+int	BIO_indent(BIO *b,int indent,int max);
+long	BIO_ctrl(BIO *bp,int cmd,long larg,void *parg);
+long BIO_callback_ctrl(BIO *b, int cmd, void (*fp)(struct bio_st *, int, const char *, int, long, long));
+char *	BIO_ptr_ctrl(BIO *bp,int cmd,long larg);
+long	BIO_int_ctrl(BIO *bp,int cmd,long larg,int iarg);
+BIO *	BIO_push(BIO *b,BIO *append);
+BIO *	BIO_pop(BIO *b);
+void	BIO_free_all(BIO *a);
+BIO *	BIO_find_type(BIO *b,int bio_type);
+BIO *	BIO_next(BIO *b);
+BIO *	BIO_get_retry_BIO(BIO *bio, int *reason);
+int	BIO_get_retry_reason(BIO *bio);
+BIO *	BIO_dup_chain(BIO *in);
+
+int BIO_nread0(BIO *bio, char **buf);
+int BIO_nread(BIO *bio, char **buf, int num);
+int BIO_nwrite0(BIO *bio, char **buf);
+int BIO_nwrite(BIO *bio, char **buf, int num);
+
+#ifndef OPENSSL_SYS_WIN16
+long BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+	long argl,long ret);
+#else
+long _far _loadds BIO_debug_callback(BIO *bio,int cmd,const char *argp,int argi,
+	long argl,long ret);
+#endif
+
+BIO_METHOD *BIO_s_mem(void);
+BIO *BIO_new_mem_buf(void *buf, int len);
+BIO_METHOD *BIO_s_socket(void);
+BIO_METHOD *BIO_s_connect(void);
+BIO_METHOD *BIO_s_accept(void);
+BIO_METHOD *BIO_s_fd(void);
+#ifndef OPENSSL_SYS_OS2
+BIO_METHOD *BIO_s_log(void);
+#endif
+BIO_METHOD *BIO_s_bio(void);
+BIO_METHOD *BIO_s_null(void);
+BIO_METHOD *BIO_f_null(void);
+BIO_METHOD *BIO_f_buffer(void);
+#ifdef OPENSSL_SYS_VMS
+BIO_METHOD *BIO_f_linebuffer(void);
+#endif
+BIO_METHOD *BIO_f_nbio_test(void);
+#ifndef OPENSSL_NO_DGRAM
+BIO_METHOD *BIO_s_datagram(void);
+#endif
+
+/* BIO_METHOD *BIO_f_ber(void); */
+
+int BIO_sock_should_retry(int i);
+int BIO_sock_non_fatal_error(int error);
+int BIO_dgram_non_fatal_error(int error);
+
+int BIO_fd_should_retry(int i);
+int BIO_fd_non_fatal_error(int error);
+int BIO_dump_cb(int (*cb)(const void *data, size_t len, void *u),
+		void *u, const char *s, int len);
+int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
+		       void *u, const char *s, int len, int indent);
+int BIO_dump(BIO *b,const char *bytes,int len);
+int BIO_dump_indent(BIO *b,const char *bytes,int len,int indent);
+#ifndef OPENSSL_NO_FP_API
+int BIO_dump_fp(FILE *fp, const char *s, int len);
+int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
+#endif
+struct hostent *BIO_gethostbyname(const char *name);
+/* We might want a thread-safe interface too:
+ * struct hostent *BIO_gethostbyname_r(const char *name,
+ *     struct hostent *result, void *buffer, size_t buflen);
+ * or something similar (caller allocates a struct hostent,
+ * pointed to by "result", and additional buffer space for the various
+ * substructures; if the buffer does not suffice, NULL is returned
+ * and an appropriate error code is set).
+ */
+int BIO_sock_error(int sock);
+int BIO_socket_ioctl(int fd, long type, void *arg);
+int BIO_socket_nbio(int fd,int mode);
+int BIO_get_port(const char *str, unsigned short *port_ptr);
+int BIO_get_host_ip(const char *str, unsigned char *ip);
+int BIO_get_accept_socket(char *host_port,int mode);
+int BIO_accept(int sock,char **ip_port);
+int BIO_sock_init(void );
+void BIO_sock_cleanup(void);
+int BIO_set_tcp_ndelay(int sock,int turn_on);
+
+BIO *BIO_new_socket(int sock, int close_flag);
+BIO *BIO_new_dgram(int fd, int close_flag);
+BIO *BIO_new_fd(int fd, int close_flag);
+BIO *BIO_new_connect(char *host_port);
+BIO *BIO_new_accept(char *host_port);
+
+int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
+	BIO **bio2, size_t writebuf2);
+/* If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints.
+ * Otherwise returns 0 and sets *bio1 and *bio2 to NULL.
+ * Size 0 uses default value.
+ */
+
+void BIO_copy_next_retry(BIO *b);
+
+/*long BIO_ghbn_ctrl(int cmd,int iarg,char *parg);*/
+
+#ifndef __GNUC__
+#define __attribute__(x)
+#endif
+int BIO_printf(BIO *bio, const char *format, ...)
+	__attribute__((__format__(__printf__,2,3)));
+int BIO_vprintf(BIO *bio, const char *format, va_list args)
+	__attribute__((__format__(__printf__,2,0)));
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
+	__attribute__((__format__(__printf__,3,4)));
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
+	__attribute__((__format__(__printf__,3,0)));
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_BIO_strings(void);
+
+/* Error codes for the BIO functions. */
+
+/* Function codes. */
+#define BIO_F_ACPT_STATE				 100
+#define BIO_F_BIO_ACCEPT				 101
+#define BIO_F_BIO_BER_GET_HEADER			 102
+#define BIO_F_BIO_CALLBACK_CTRL				 131
+#define BIO_F_BIO_CTRL					 103
+#define BIO_F_BIO_GETHOSTBYNAME				 120
+#define BIO_F_BIO_GETS					 104
+#define BIO_F_BIO_GET_ACCEPT_SOCKET			 105
+#define BIO_F_BIO_GET_HOST_IP				 106
+#define BIO_F_BIO_GET_PORT				 107
+#define BIO_F_BIO_MAKE_PAIR				 121
+#define BIO_F_BIO_NEW					 108
+#define BIO_F_BIO_NEW_FILE				 109
+#define BIO_F_BIO_NEW_MEM_BUF				 126
+#define BIO_F_BIO_NREAD					 123
+#define BIO_F_BIO_NREAD0				 124
+#define BIO_F_BIO_NWRITE				 125
+#define BIO_F_BIO_NWRITE0				 122
+#define BIO_F_BIO_PUTS					 110
+#define BIO_F_BIO_READ					 111
+#define BIO_F_BIO_SOCK_INIT				 112
+#define BIO_F_BIO_WRITE					 113
+#define BIO_F_BUFFER_CTRL				 114
+#define BIO_F_CONN_CTRL					 127
+#define BIO_F_CONN_STATE				 115
+#define BIO_F_FILE_CTRL					 116
+#define BIO_F_FILE_READ					 130
+#define BIO_F_LINEBUFFER_CTRL				 129
+#define BIO_F_MEM_READ					 128
+#define BIO_F_MEM_WRITE					 117
+#define BIO_F_SSL_NEW					 118
+#define BIO_F_WSASTARTUP				 119
+
+/* Reason codes. */
+#define BIO_R_ACCEPT_ERROR				 100
+#define BIO_R_BAD_FOPEN_MODE				 101
+#define BIO_R_BAD_HOSTNAME_LOOKUP			 102
+#define BIO_R_BROKEN_PIPE				 124
+#define BIO_R_CONNECT_ERROR				 103
+#define BIO_R_EOF_ON_MEMORY_BIO				 127
+#define BIO_R_ERROR_SETTING_NBIO			 104
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET	 105
+#define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET	 106
+#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET		 107
+#define BIO_R_INVALID_ARGUMENT				 125
+#define BIO_R_INVALID_IP_ADDRESS			 108
+#define BIO_R_IN_USE					 123
+#define BIO_R_KEEPALIVE					 109
+#define BIO_R_NBIO_CONNECT_ERROR			 110
+#define BIO_R_NO_ACCEPT_PORT_SPECIFIED			 111
+#define BIO_R_NO_HOSTNAME_SPECIFIED			 112
+#define BIO_R_NO_PORT_DEFINED				 113
+#define BIO_R_NO_PORT_SPECIFIED				 114
+#define BIO_R_NO_SUCH_FILE				 128
+#define BIO_R_NULL_PARAMETER				 115
+#define BIO_R_TAG_MISMATCH				 116
+#define BIO_R_UNABLE_TO_BIND_SOCKET			 117
+#define BIO_R_UNABLE_TO_CREATE_SOCKET			 118
+#define BIO_R_UNABLE_TO_LISTEN_SOCKET			 119
+#define BIO_R_UNINITIALIZED				 120
+#define BIO_R_UNSUPPORTED_METHOD			 121
+#define BIO_R_WRITE_TO_READ_ONLY_BIO			 126
+#define BIO_R_WSASTARTUP				 122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/blowfish.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/blowfish.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/blowfish.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,127 @@
+/* crypto/bf/blowfish.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BLOWFISH_H
+#define HEADER_BLOWFISH_H
+
+#include <openssl/e_os2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_BF
+#error BF is disabled.
+#endif
+
+#define BF_ENCRYPT	1
+#define BF_DECRYPT	0
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! BF_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! BF_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define BF_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define BF_LONG unsigned long
+#define BF_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *					<appro@fy.chalmers.se>
+ */
+#else
+#define BF_LONG unsigned int
+#endif
+
+#define BF_ROUNDS	16
+#define BF_BLOCK	8
+
+typedef struct bf_key_st
+	{
+	BF_LONG P[BF_ROUNDS+2];
+	BF_LONG S[4*256];
+	} BF_KEY;
+
+ 
+void BF_set_key(BF_KEY *key, int len, const unsigned char *data);
+
+void BF_encrypt(BF_LONG *data,const BF_KEY *key);
+void BF_decrypt(BF_LONG *data,const BF_KEY *key);
+
+void BF_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	const BF_KEY *key, int enc);
+void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	const BF_KEY *schedule, unsigned char *ivec, int enc);
+void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	const BF_KEY *schedule, unsigned char *ivec, int *num, int enc);
+void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length,
+	const BF_KEY *schedule, unsigned char *ivec, int *num);
+const char *BF_options(void);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/bn.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/bn.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/bn.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,807 @@
+/* crypto/bn/bn.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the Eric Young open source
+ * license provided above.
+ *
+ * The binary polynomial arithmetic software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_BN_H
+#define HEADER_BN_H
+
+#include <openssl/e_os2.h>
+#ifndef OPENSSL_NO_FP_API
+#include <stdio.h> /* FILE */
+#endif
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* These preprocessor symbols control various aspects of the bignum headers and
+ * library code. They're not defined by any "normal" configuration, as they are
+ * intended for development and testing purposes. NB: defining all three can be
+ * useful for debugging application code as well as openssl itself.
+ *
+ * BN_DEBUG - turn on various debugging alterations to the bignum code
+ * BN_DEBUG_RAND - uses random poisoning of unused words to trip up
+ * mismanagement of bignum internals. You must also define BN_DEBUG.
+ */
+/* #define BN_DEBUG */
+/* #define BN_DEBUG_RAND */
+
+#define BN_MUL_COMBA
+#define BN_SQR_COMBA
+#define BN_RECURSION
+
+/* This next option uses the C libraries (2 word)/(1 word) function.
+ * If it is not defined, I use my C version (which is slower).
+ * The reason for this flag is that when the particular C compiler
+ * library routine is used, and the library is linked with a different
+ * compiler, the library is missing.  This mostly happens when the
+ * library is built with gcc and then linked using normal cc.  This would
+ * be a common occurrence because gcc normally produces code that is
+ * 2 times faster than system compilers for the big number stuff.
+ * For machines with only one compiler (or shared libraries), this should
+ * be on.  Again this in only really a problem on machines
+ * using "long long's", are 32bit, and are not using my assembler code. */
+#if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \
+    defined(OPENSSL_SYS_WIN32) || defined(linux)
+# ifndef BN_DIV2W
+#  define BN_DIV2W
+# endif
+#endif
+
+/* assuming long is 64bit - this is the DEC Alpha
+ * unsigned long long is only 64 bits :-(, don't define
+ * BN_LLONG for the DEC Alpha */
+#ifdef SIXTY_FOUR_BIT_LONG
+#define BN_ULLONG	unsigned long long
+#define BN_ULONG	unsigned long
+#define BN_LONG		long
+#define BN_BITS		128
+#define BN_BYTES	8
+#define BN_BITS2	64
+#define BN_BITS4	32
+#define BN_MASK		(0xffffffffffffffffffffffffffffffffLL)
+#define BN_MASK2	(0xffffffffffffffffL)
+#define BN_MASK2l	(0xffffffffL)
+#define BN_MASK2h	(0xffffffff00000000L)
+#define BN_MASK2h1	(0xffffffff80000000L)
+#define BN_TBIT		(0x8000000000000000L)
+#define BN_DEC_CONV	(10000000000000000000UL)
+#define BN_DEC_FMT1	"%lu"
+#define BN_DEC_FMT2	"%019lu"
+#define BN_DEC_NUM	19
+#endif
+
+/* This is where the long long data type is 64 bits, but long is 32.
+ * For machines where there are 64bit registers, this is the mode to use.
+ * IRIX, on R4000 and above should use this mode, along with the relevant
+ * assembler code :-).  Do NOT define BN_LLONG.
+ */
+#ifdef SIXTY_FOUR_BIT
+#undef BN_LLONG
+#undef BN_ULLONG
+#define BN_ULONG	unsigned long long
+#define BN_LONG		long long
+#define BN_BITS		128
+#define BN_BYTES	8
+#define BN_BITS2	64
+#define BN_BITS4	32
+#define BN_MASK2	(0xffffffffffffffffLL)
+#define BN_MASK2l	(0xffffffffL)
+#define BN_MASK2h	(0xffffffff00000000LL)
+#define BN_MASK2h1	(0xffffffff80000000LL)
+#define BN_TBIT		(0x8000000000000000LL)
+#define BN_DEC_CONV	(10000000000000000000ULL)
+#define BN_DEC_FMT1	"%llu"
+#define BN_DEC_FMT2	"%019llu"
+#define BN_DEC_NUM	19
+#endif
+
+#ifdef THIRTY_TWO_BIT
+#ifdef BN_LLONG
+# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
+#  define BN_ULLONG	unsigned __int64
+# else
+#  define BN_ULLONG	unsigned long long
+# endif
+#endif
+#define BN_ULONG	unsigned long
+#define BN_LONG		long
+#define BN_BITS		64
+#define BN_BYTES	4
+#define BN_BITS2	32
+#define BN_BITS4	16
+#ifdef OPENSSL_SYS_WIN32
+/* VC++ doesn't like the LL suffix */
+#define BN_MASK		(0xffffffffffffffffL)
+#else
+#define BN_MASK		(0xffffffffffffffffLL)
+#endif
+#define BN_MASK2	(0xffffffffL)
+#define BN_MASK2l	(0xffff)
+#define BN_MASK2h1	(0xffff8000L)
+#define BN_MASK2h	(0xffff0000L)
+#define BN_TBIT		(0x80000000L)
+#define BN_DEC_CONV	(1000000000L)
+#define BN_DEC_FMT1	"%lu"
+#define BN_DEC_FMT2	"%09lu"
+#define BN_DEC_NUM	9
+#endif
+
+#ifdef SIXTEEN_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG	unsigned long
+#define BN_ULONG	unsigned short
+#define BN_LONG		short
+#define BN_BITS		32
+#define BN_BYTES	2
+#define BN_BITS2	16
+#define BN_BITS4	8
+#define BN_MASK		(0xffffffff)
+#define BN_MASK2	(0xffff)
+#define BN_MASK2l	(0xff)
+#define BN_MASK2h1	(0xff80)
+#define BN_MASK2h	(0xff00)
+#define BN_TBIT		(0x8000)
+#define BN_DEC_CONV	(100000)
+#define BN_DEC_FMT1	"%u"
+#define BN_DEC_FMT2	"%05u"
+#define BN_DEC_NUM	5
+#endif
+
+#ifdef EIGHT_BIT
+#ifndef BN_DIV2W
+#define BN_DIV2W
+#endif
+#define BN_ULLONG	unsigned short
+#define BN_ULONG	unsigned char
+#define BN_LONG		char
+#define BN_BITS		16
+#define BN_BYTES	1
+#define BN_BITS2	8
+#define BN_BITS4	4
+#define BN_MASK		(0xffff)
+#define BN_MASK2	(0xff)
+#define BN_MASK2l	(0xf)
+#define BN_MASK2h1	(0xf8)
+#define BN_MASK2h	(0xf0)
+#define BN_TBIT		(0x80)
+#define BN_DEC_CONV	(100)
+#define BN_DEC_FMT1	"%u"
+#define BN_DEC_FMT2	"%02u"
+#define BN_DEC_NUM	2
+#endif
+
+#define BN_DEFAULT_BITS	1280
+
+#define BN_FLG_MALLOCED		0x01
+#define BN_FLG_STATIC_DATA	0x02
+#define BN_FLG_EXP_CONSTTIME	0x04 /* avoid leaking exponent information through timings
+                            	      * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) */
+#ifndef OPENSSL_NO_DEPRECATED
+#define BN_FLG_FREE		0x8000	/* used for debuging */
+#endif
+#define BN_set_flags(b,n)	((b)->flags|=(n))
+#define BN_get_flags(b,n)	((b)->flags&(n))
+
+/* get a clone of a BIGNUM with changed flags, for *temporary* use only
+ * (the two BIGNUMs cannot not be used in parallel!) */
+#define BN_with_flags(dest,b,n)  ((dest)->d=(b)->d, \
+                                  (dest)->top=(b)->top, \
+                                  (dest)->dmax=(b)->dmax, \
+                                  (dest)->neg=(b)->neg, \
+                                  (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \
+                                                 |  ((b)->flags & ~BN_FLG_MALLOCED) \
+                                                 |  BN_FLG_STATIC_DATA \
+                                                 |  (n)))
+
+/* Already declared in ossl_typ.h */
+#if 0
+typedef struct bignum_st BIGNUM;
+/* Used for temp variables (declaration hidden in bn_lcl.h) */
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+#endif
+
+struct bignum_st
+	{
+	BN_ULONG *d;	/* Pointer to an array of 'BN_BITS2' bit chunks. */
+	int top;	/* Index of last used d +1. */
+	/* The next are internal book keeping for bn_expand. */
+	int dmax;	/* Size of the d array. */
+	int neg;	/* one if the number is negative */
+	int flags;
+	};
+
+/* Used for montgomery multiplication */
+struct bn_mont_ctx_st
+	{
+	int ri;        /* number of bits in R */
+	BIGNUM RR;     /* used to convert to montgomery form */
+	BIGNUM N;      /* The modulus */
+	BIGNUM Ni;     /* R*(1/R mod N) - N*Ni = 1
+	                * (Ni is only stored for bignum algorithm) */
+	BN_ULONG n0;   /* least significant word of Ni */
+	int flags;
+	};
+
+/* Used for reciprocal division/mod functions
+ * It cannot be shared between threads
+ */
+struct bn_recp_ctx_st
+	{
+	BIGNUM N;	/* the divisor */
+	BIGNUM Nr;	/* the reciprocal */
+	int num_bits;
+	int shift;
+	int flags;
+	};
+
+/* Used for slow "generation" functions. */
+struct bn_gencb_st
+	{
+	unsigned int ver;	/* To handle binary (in)compatibility */
+	void *arg;		/* callback-specific data */
+	union
+		{
+		/* if(ver==1) - handles old style callbacks */
+		void (*cb_1)(int, int, void *);
+		/* if(ver==2) - new callback style */
+		int (*cb_2)(int, int, BN_GENCB *);
+		} cb;
+	};
+/* Wrapper function to make using BN_GENCB easier,  */
+int BN_GENCB_call(BN_GENCB *cb, int a, int b);
+/* Macro to populate a BN_GENCB structure with an "old"-style callback */
+#define BN_GENCB_set_old(gencb, callback, cb_arg) { \
+		BN_GENCB *tmp_gencb = (gencb); \
+		tmp_gencb->ver = 1; \
+		tmp_gencb->arg = (cb_arg); \
+		tmp_gencb->cb.cb_1 = (callback); }
+/* Macro to populate a BN_GENCB structure with a "new"-style callback */
+#define BN_GENCB_set(gencb, callback, cb_arg) { \
+		BN_GENCB *tmp_gencb = (gencb); \
+		tmp_gencb->ver = 2; \
+		tmp_gencb->arg = (cb_arg); \
+		tmp_gencb->cb.cb_2 = (callback); }
+
+#define BN_prime_checks 0 /* default: select number of iterations
+			     based on the size of the number */
+
+/* number of Miller-Rabin iterations for an error rate  of less than 2^-80
+ * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
+ * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
+ * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
+#define BN_prime_checks_for_size(b) ((b) >= 1300 ?  2 : \
+                                (b) >=  850 ?  3 : \
+                                (b) >=  650 ?  4 : \
+                                (b) >=  550 ?  5 : \
+                                (b) >=  450 ?  6 : \
+                                (b) >=  400 ?  7 : \
+                                (b) >=  350 ?  8 : \
+                                (b) >=  300 ?  9 : \
+                                (b) >=  250 ? 12 : \
+                                (b) >=  200 ? 15 : \
+                                (b) >=  150 ? 18 : \
+                                /* b >= 100 */ 27)
+
+#define BN_num_bytes(a)	((BN_num_bits(a)+7)/8)
+
+/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */
+#define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \
+				(((w) == 0) && ((a)->top == 0)))
+#define BN_is_zero(a)       ((a)->top == 0)
+#define BN_is_one(a)        (BN_abs_is_word((a),1) && !(a)->neg)
+#define BN_is_word(a,w)     (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg))
+#define BN_is_odd(a)	    (((a)->top > 0) && ((a)->d[0] & 1))
+
+#define BN_one(a)	(BN_set_word((a),1))
+#define BN_zero_ex(a) \
+	do { \
+		BIGNUM *_tmp_bn = (a); \
+		_tmp_bn->top = 0; \
+		_tmp_bn->neg = 0; \
+	} while(0)
+#ifdef OPENSSL_NO_DEPRECATED
+#define BN_zero(a)	BN_zero_ex(a)
+#else
+#define BN_zero(a)	(BN_set_word((a),0))
+#endif
+
+const BIGNUM *BN_value_one(void);
+char *	BN_options(void);
+BN_CTX *BN_CTX_new(void);
+#ifndef OPENSSL_NO_DEPRECATED
+void	BN_CTX_init(BN_CTX *c);
+#endif
+void	BN_CTX_free(BN_CTX *c);
+void	BN_CTX_start(BN_CTX *ctx);
+BIGNUM *BN_CTX_get(BN_CTX *ctx);
+void	BN_CTX_end(BN_CTX *ctx);
+int     BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int     BN_pseudo_rand(BIGNUM *rnd, int bits, int top,int bottom);
+int	BN_rand_range(BIGNUM *rnd, BIGNUM *range);
+int	BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range);
+int	BN_num_bits(const BIGNUM *a);
+int	BN_num_bits_word(BN_ULONG);
+BIGNUM *BN_new(void);
+void	BN_init(BIGNUM *);
+void	BN_clear_free(BIGNUM *a);
+BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+void	BN_swap(BIGNUM *a, BIGNUM *b);
+BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
+int	BN_bn2bin(const BIGNUM *a, unsigned char *to);
+BIGNUM *BN_mpi2bn(const unsigned char *s,int len,BIGNUM *ret);
+int	BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+int	BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+int	BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+int	BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
+/* BN_set_negative(): sets sign of a bignum */
+void	BN_set_negative(BIGNUM *b, int n);
+/* BN_get_negative():  returns 1 if the bignum is < 0 and 0 otherwise */
+#define BN_is_negative(a) ((a)->neg != 0)
+
+int	BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+	BN_CTX *ctx);
+#define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx))
+int	BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+int	BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
+int	BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m);
+int	BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m);
+int	BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, BN_CTX *ctx);
+int	BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m);
+
+BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+int	BN_mul_word(BIGNUM *a, BN_ULONG w);
+int	BN_add_word(BIGNUM *a, BN_ULONG w);
+int	BN_sub_word(BIGNUM *a, BN_ULONG w);
+int	BN_set_word(BIGNUM *a, BN_ULONG w);
+BN_ULONG BN_get_word(const BIGNUM *a);
+
+int	BN_cmp(const BIGNUM *a, const BIGNUM *b);
+void	BN_free(BIGNUM *a);
+int	BN_is_bit_set(const BIGNUM *a, int n);
+int	BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+int	BN_lshift1(BIGNUM *r, const BIGNUM *a);
+int	BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,BN_CTX *ctx);
+
+int	BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m,BN_CTX *ctx);
+int	BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont);
+int	BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+int	BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1,
+	const BIGNUM *a2, const BIGNUM *p2,const BIGNUM *m,
+	BN_CTX *ctx,BN_MONT_CTX *m_ctx);
+int	BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m,BN_CTX *ctx);
+
+int	BN_mask_bits(BIGNUM *a,int n);
+#ifndef OPENSSL_NO_FP_API
+int	BN_print_fp(FILE *fp, const BIGNUM *a);
+#endif
+#ifdef HEADER_BIO_H
+int	BN_print(BIO *fp, const BIGNUM *a);
+#else
+int	BN_print(void *fp, const BIGNUM *a);
+#endif
+int	BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx);
+int	BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
+int	BN_rshift1(BIGNUM *r, const BIGNUM *a);
+void	BN_clear(BIGNUM *a);
+BIGNUM *BN_dup(const BIGNUM *a);
+int	BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+int	BN_set_bit(BIGNUM *a, int n);
+int	BN_clear_bit(BIGNUM *a, int n);
+char *	BN_bn2hex(const BIGNUM *a);
+char *	BN_bn2dec(const BIGNUM *a);
+int 	BN_hex2bn(BIGNUM **a, const char *str);
+int 	BN_dec2bn(BIGNUM **a, const char *str);
+int	BN_gcd(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx);
+int	BN_kronecker(const BIGNUM *a,const BIGNUM *b,BN_CTX *ctx); /* returns -2 for error */
+BIGNUM *BN_mod_inverse(BIGNUM *ret,
+	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+BIGNUM *BN_mod_sqrt(BIGNUM *ret,
+	const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+
+/* Deprecated versions */
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
+	const BIGNUM *add, const BIGNUM *rem,
+	void (*callback)(int,int,void *),void *cb_arg);
+int	BN_is_prime(const BIGNUM *p,int nchecks,
+	void (*callback)(int,int,void *),
+	BN_CTX *ctx,void *cb_arg);
+int	BN_is_prime_fasttest(const BIGNUM *p,int nchecks,
+	void (*callback)(int,int,void *),BN_CTX *ctx,void *cb_arg,
+	int do_trial_division);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* Newer versions */
+int	BN_generate_prime_ex(BIGNUM *ret,int bits,int safe, const BIGNUM *add,
+		const BIGNUM *rem, BN_GENCB *cb);
+int	BN_is_prime_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx, BN_GENCB *cb);
+int	BN_is_prime_fasttest_ex(const BIGNUM *p,int nchecks, BN_CTX *ctx,
+		int do_trial_division, BN_GENCB *cb);
+
+BN_MONT_CTX *BN_MONT_CTX_new(void );
+void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+int BN_mod_mul_montgomery(BIGNUM *r,const BIGNUM *a,const BIGNUM *b,
+	BN_MONT_CTX *mont, BN_CTX *ctx);
+#define BN_to_montgomery(r,a,mont,ctx)	BN_mod_mul_montgomery(\
+	(r),(a),&((mont)->RR),(mont),(ctx))
+int BN_from_montgomery(BIGNUM *r,const BIGNUM *a,
+	BN_MONT_CTX *mont, BN_CTX *ctx);
+void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *mod,BN_CTX *ctx);
+BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
+BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock,
+					const BIGNUM *mod, BN_CTX *ctx);
+
+/* BN_BLINDING flags */
+#define	BN_BLINDING_NO_UPDATE	0x00000001
+#define	BN_BLINDING_NO_RECREATE	0x00000002
+
+BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod);
+void BN_BLINDING_free(BN_BLINDING *b);
+int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
+int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
+void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
+unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
+void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
+BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
+	const BIGNUM *e, BIGNUM *m, BN_CTX *ctx,
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx),
+	BN_MONT_CTX *m_ctx);
+
+#ifndef OPENSSL_NO_DEPRECATED
+void BN_set_params(int mul,int high,int low,int mont);
+int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */
+#endif
+
+void	BN_RECP_CTX_init(BN_RECP_CTX *recp);
+BN_RECP_CTX *BN_RECP_CTX_new(void);
+void	BN_RECP_CTX_free(BN_RECP_CTX *recp);
+int	BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
+int	BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y,
+	BN_RECP_CTX *recp,BN_CTX *ctx);
+int	BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	const BIGNUM *m, BN_CTX *ctx);
+int	BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
+	BN_RECP_CTX *recp, BN_CTX *ctx);
+
+/* Functions for arithmetic over binary polynomials represented by BIGNUMs. 
+ *
+ * The BIGNUM::neg property of BIGNUMs representing binary polynomials is
+ * ignored.
+ *
+ * Note that input arguments are not const so that their bit arrays can
+ * be expanded to the appropriate size if needed.
+ */
+
+int	BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); /*r = a + b*/
+#define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b)
+int	BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); /*r=a mod p*/
+int	BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *p, BN_CTX *ctx); /* r = (a * b) mod p */
+int	BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	BN_CTX *ctx); /* r = (a * a) mod p */
+int	BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p,
+	BN_CTX *ctx); /* r = (1 / b) mod p */
+int	BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *p, BN_CTX *ctx); /* r = (a / b) mod p */
+int	BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const BIGNUM *p, BN_CTX *ctx); /* r = (a ^ b) mod p */
+int	BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	BN_CTX *ctx); /* r = sqrt(a) mod p */
+int	BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+	BN_CTX *ctx); /* r^2 + r = a mod p */
+#define BN_GF2m_cmp(a, b) BN_ucmp((a), (b))
+/* Some functions allow for representation of the irreducible polynomials
+ * as an unsigned int[], say p.  The irreducible f(t) is then of the form:
+ *     t^p[0] + t^p[1] + ... + t^p[k]
+ * where m = p[0] > p[1] > ... > p[k] = 0.
+ */
+int	BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[]);
+	/* r = a mod p */
+int	BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const unsigned int p[], BN_CTX *ctx); /* r = (a * b) mod p */
+int	BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const unsigned int p[],
+	BN_CTX *ctx); /* r = (a * a) mod p */
+int	BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const unsigned int p[],
+	BN_CTX *ctx); /* r = (1 / b) mod p */
+int	BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const unsigned int p[], BN_CTX *ctx); /* r = (a / b) mod p */
+int	BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
+	const unsigned int p[], BN_CTX *ctx); /* r = (a ^ b) mod p */
+int	BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a,
+	const unsigned int p[], BN_CTX *ctx); /* r = sqrt(a) mod p */
+int	BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a,
+	const unsigned int p[], BN_CTX *ctx); /* r^2 + r = a mod p */
+int	BN_GF2m_poly2arr(const BIGNUM *a, unsigned int p[], int max);
+int	BN_GF2m_arr2poly(const unsigned int p[], BIGNUM *a);
+
+/* faster mod functions for the 'NIST primes' 
+ * 0 <= a < p^2 */
+int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
+
+const BIGNUM *BN_get0_nist_prime_192(void);
+const BIGNUM *BN_get0_nist_prime_224(void);
+const BIGNUM *BN_get0_nist_prime_256(void);
+const BIGNUM *BN_get0_nist_prime_384(void);
+const BIGNUM *BN_get0_nist_prime_521(void);
+
+/* library internal functions */
+
+#define bn_expand(a,bits) ((((((bits+BN_BITS2-1))/BN_BITS2)) <= (a)->dmax)?\
+	(a):bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2))
+#define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words)))
+BIGNUM *bn_expand2(BIGNUM *a, int words);
+#ifndef OPENSSL_NO_DEPRECATED
+BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */
+#endif
+
+/* Bignum consistency macros
+ * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
+ * bignum data after direct manipulations on the data. There is also an
+ * "internal" macro, bn_check_top(), for verifying that there are no leading
+ * zeroes. Unfortunately, some auditing is required due to the fact that
+ * bn_fix_top() has become an overabused duct-tape because bignum data is
+ * occasionally passed around in an inconsistent state. So the following
+ * changes have been made to sort this out;
+ * - bn_fix_top()s implementation has been moved to bn_correct_top()
+ * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
+ *   bn_check_top() is as before.
+ * - if BN_DEBUG *is* defined;
+ *   - bn_check_top() tries to pollute unused words even if the bignum 'top' is
+ *     consistent. (ed: only if BN_DEBUG_RAND is defined)
+ *   - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
+ * The idea is to have debug builds flag up inconsistent bignums when they
+ * occur. If that occurs in a bn_fix_top(), we examine the code in question; if
+ * the use of bn_fix_top() was appropriate (ie. it follows directly after code
+ * that manipulates the bignum) it is converted to bn_correct_top(), and if it
+ * was not appropriate, we convert it permanently to bn_check_top() and track
+ * down the cause of the bug. Eventually, no internal code should be using the
+ * bn_fix_top() macro. External applications and libraries should try this with
+ * their own code too, both in terms of building against the openssl headers
+ * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
+ * defined. This not only improves external code, it provides more test
+ * coverage for openssl's own code.
+ */
+
+#ifdef BN_DEBUG
+
+/* We only need assert() when debugging */
+#include <assert.h>
+
+#ifdef BN_DEBUG_RAND
+/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */
+#ifndef RAND_pseudo_bytes
+int RAND_pseudo_bytes(unsigned char *buf,int num);
+#define BN_DEBUG_TRIX
+#endif
+#define bn_pollute(a) \
+	do { \
+		const BIGNUM *_bnum1 = (a); \
+		if(_bnum1->top < _bnum1->dmax) { \
+			unsigned char _tmp_char; \
+			/* We cast away const without the compiler knowing, any \
+			 * *genuinely* constant variables that aren't mutable \
+			 * wouldn't be constructed with top!=dmax. */ \
+			BN_ULONG *_not_const; \
+			memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \
+			RAND_pseudo_bytes(&_tmp_char, 1); \
+			memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \
+				(_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \
+		} \
+	} while(0)
+#ifdef BN_DEBUG_TRIX
+#undef RAND_pseudo_bytes
+#endif
+#else
+#define bn_pollute(a)
+#endif
+#define bn_check_top(a) \
+	do { \
+		const BIGNUM *_bnum2 = (a); \
+		assert((_bnum2->top == 0) || \
+				(_bnum2->d[_bnum2->top - 1] != 0)); \
+		bn_pollute(_bnum2); \
+	} while(0)
+
+#define bn_fix_top(a)		bn_check_top(a)
+
+#else /* !BN_DEBUG */
+
+#define bn_pollute(a)
+#define bn_check_top(a)
+#define bn_fix_top(a)		bn_correct_top(a)
+
+#endif
+
+#define bn_correct_top(a) \
+        { \
+        BN_ULONG *ftl; \
+	if ((a)->top > 0) \
+		{ \
+		for (ftl= &((a)->d[(a)->top-1]); (a)->top > 0; (a)->top--) \
+		if (*(ftl--)) break; \
+		} \
+	bn_pollute(a); \
+	}
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
+void     bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
+BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,int num);
+
+int BN_bntest_rand(BIGNUM *rnd, int bits, int top,int bottom);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_BN_strings(void);
+
+/* Error codes for the BN functions. */
+
+/* Function codes. */
+#define BN_F_BNRAND					 127
+#define BN_F_BN_BLINDING_CONVERT_EX			 100
+#define BN_F_BN_BLINDING_CREATE_PARAM			 128
+#define BN_F_BN_BLINDING_INVERT_EX			 101
+#define BN_F_BN_BLINDING_NEW				 102
+#define BN_F_BN_BLINDING_UPDATE				 103
+#define BN_F_BN_BN2DEC					 104
+#define BN_F_BN_BN2HEX					 105
+#define BN_F_BN_CTX_GET					 116
+#define BN_F_BN_CTX_NEW					 106
+#define BN_F_BN_CTX_START				 129
+#define BN_F_BN_DIV					 107
+#define BN_F_BN_DIV_RECP				 130
+#define BN_F_BN_EXP					 123
+#define BN_F_BN_EXPAND2					 108
+#define BN_F_BN_EXPAND_INTERNAL				 120
+#define BN_F_BN_GF2M_MOD				 131
+#define BN_F_BN_GF2M_MOD_EXP				 132
+#define BN_F_BN_GF2M_MOD_MUL				 133
+#define BN_F_BN_GF2M_MOD_SOLVE_QUAD			 134
+#define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR			 135
+#define BN_F_BN_GF2M_MOD_SQR				 136
+#define BN_F_BN_GF2M_MOD_SQRT				 137
+#define BN_F_BN_MOD_EXP2_MONT				 118
+#define BN_F_BN_MOD_EXP_MONT				 109
+#define BN_F_BN_MOD_EXP_MONT_CONSTTIME			 124
+#define BN_F_BN_MOD_EXP_MONT_WORD			 117
+#define BN_F_BN_MOD_EXP_RECP				 125
+#define BN_F_BN_MOD_EXP_SIMPLE				 126
+#define BN_F_BN_MOD_INVERSE				 110
+#define BN_F_BN_MOD_LSHIFT_QUICK			 119
+#define BN_F_BN_MOD_MUL_RECIPROCAL			 111
+#define BN_F_BN_MOD_SQRT				 121
+#define BN_F_BN_MPI2BN					 112
+#define BN_F_BN_NEW					 113
+#define BN_F_BN_RAND					 114
+#define BN_F_BN_RAND_RANGE				 122
+#define BN_F_BN_USUB					 115
+
+/* Reason codes. */
+#define BN_R_ARG2_LT_ARG3				 100
+#define BN_R_BAD_RECIPROCAL				 101
+#define BN_R_BIGNUM_TOO_LONG				 114
+#define BN_R_CALLED_WITH_EVEN_MODULUS			 102
+#define BN_R_DIV_BY_ZERO				 103
+#define BN_R_ENCODING_ERROR				 104
+#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA		 105
+#define BN_R_INPUT_NOT_REDUCED				 110
+#define BN_R_INVALID_LENGTH				 106
+#define BN_R_INVALID_RANGE				 115
+#define BN_R_NOT_A_SQUARE				 111
+#define BN_R_NOT_INITIALIZED				 107
+#define BN_R_NO_INVERSE					 108
+#define BN_R_NO_SOLUTION				 116
+#define BN_R_P_IS_NOT_PRIME				 112
+#define BN_R_TOO_MANY_ITERATIONS			 113
+#define BN_R_TOO_MANY_TEMPORARY_VARIABLES		 109
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/buffer.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/buffer.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/buffer.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,118 @@
+/* crypto/buffer/buffer.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_BUFFER_H
+#define HEADER_BUFFER_H
+
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <stddef.h>
+
+#if !defined(NO_SYS_TYPES_H)
+#include <sys/types.h>
+#endif
+
+/* Already declared in ossl_typ.h */
+/* typedef struct buf_mem_st BUF_MEM; */
+
+struct buf_mem_st
+	{
+	int length;	/* current number of bytes */
+	char *data;
+	int max;	/* size of buffer */
+	};
+
+BUF_MEM *BUF_MEM_new(void);
+void	BUF_MEM_free(BUF_MEM *a);
+int	BUF_MEM_grow(BUF_MEM *str, int len);
+int	BUF_MEM_grow_clean(BUF_MEM *str, int len);
+char *	BUF_strdup(const char *str);
+char *	BUF_strndup(const char *str, size_t siz);
+void *	BUF_memdup(const void *data, size_t siz);
+
+/* safe string functions */
+size_t BUF_strlcpy(char *dst,const char *src,size_t siz);
+size_t BUF_strlcat(char *dst,const char *src,size_t siz);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_BUF_strings(void);
+
+/* Error codes for the BUF functions. */
+
+/* Function codes. */
+#define BUF_F_BUF_MEMDUP				 103
+#define BUF_F_BUF_MEM_GROW				 100
+#define BUF_F_BUF_MEM_GROW_CLEAN			 105
+#define BUF_F_BUF_MEM_NEW				 101
+#define BUF_F_BUF_STRDUP				 102
+#define BUF_F_BUF_STRNDUP				 104
+
+/* Reason codes. */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/cast.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/cast.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/cast.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,105 @@
+/* crypto/cast/cast.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_CAST_H
+#define HEADER_CAST_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_CAST
+#error CAST is disabled.
+#endif
+
+#define CAST_ENCRYPT	1
+#define CAST_DECRYPT	0
+
+#define CAST_LONG unsigned long
+
+#define CAST_BLOCK	8
+#define CAST_KEY_LENGTH	16
+
+typedef struct cast_key_st
+	{
+	CAST_LONG data[32];
+	int short_key;	/* Use reduced rounds for short key */
+	} CAST_KEY;
+
+ 
+void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data);
+void CAST_ecb_encrypt(const unsigned char *in,unsigned char *out,CAST_KEY *key,
+		      int enc);
+void CAST_encrypt(CAST_LONG *data,CAST_KEY *key);
+void CAST_decrypt(CAST_LONG *data,CAST_KEY *key);
+void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+		      CAST_KEY *ks, unsigned char *iv, int enc);
+void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			long length, CAST_KEY *schedule, unsigned char *ivec,
+			int *num, int enc);
+void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, 
+			long length, CAST_KEY *schedule, unsigned char *ivec,
+			int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/comp.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/comp.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/comp.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,66 @@
+
+#ifndef HEADER_COMP_H
+#define HEADER_COMP_H
+
+#include <openssl/crypto.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct comp_ctx_st COMP_CTX;
+
+typedef struct comp_method_st
+	{
+	int type;		/* NID for compression library */
+	const char *name;	/* A text string to identify the library */
+	int (*init)(COMP_CTX *ctx);
+	void (*finish)(COMP_CTX *ctx);
+	int (*compress)(COMP_CTX *ctx,
+			unsigned char *out, unsigned int olen,
+			unsigned char *in, unsigned int ilen);
+	int (*expand)(COMP_CTX *ctx,
+		      unsigned char *out, unsigned int olen,
+		      unsigned char *in, unsigned int ilen);
+	/* The following two do NOTHING, but are kept for backward compatibility */
+	long (*ctrl)(void);
+	long (*callback_ctrl)(void);
+	} COMP_METHOD;
+
+struct comp_ctx_st
+	{
+	COMP_METHOD *meth;
+	unsigned long compress_in;
+	unsigned long compress_out;
+	unsigned long expand_in;
+	unsigned long expand_out;
+
+	CRYPTO_EX_DATA	ex_data;
+	};
+
+
+COMP_CTX *COMP_CTX_new(COMP_METHOD *meth);
+void COMP_CTX_free(COMP_CTX *ctx);
+int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen,
+	unsigned char *in, int ilen);
+int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen,
+	unsigned char *in, int ilen);
+COMP_METHOD *COMP_rle(void );
+COMP_METHOD *COMP_zlib(void );
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_COMP_strings(void);
+
+/* Error codes for the COMP functions. */
+
+/* Function codes. */
+
+/* Reason codes. */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/conf.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/conf.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/conf.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,253 @@
+/* crypto/conf/conf.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef  HEADER_CONF_H
+#define HEADER_CONF_H
+
+#include <openssl/bio.h>
+#include <openssl/lhash.h>
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+#include <openssl/e_os2.h>
+
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+	{
+	char *section;
+	char *name;
+	char *value;
+	} CONF_VALUE;
+
+DECLARE_STACK_OF(CONF_VALUE)
+DECLARE_STACK_OF(CONF_MODULE)
+DECLARE_STACK_OF(CONF_IMODULE)
+
+struct conf_st;
+struct conf_method_st;
+typedef struct conf_method_st CONF_METHOD;
+
+struct conf_method_st
+	{
+	const char *name;
+	CONF *(*create)(CONF_METHOD *meth);
+	int (*init)(CONF *conf);
+	int (*destroy)(CONF *conf);
+	int (*destroy_data)(CONF *conf);
+	int (*load_bio)(CONF *conf, BIO *bp, long *eline);
+	int (*dump)(const CONF *conf, BIO *bp);
+	int (*is_number)(const CONF *conf, char c);
+	int (*to_int)(const CONF *conf, char c);
+	int (*load)(CONF *conf, const char *name, long *eline);
+	};
+
+/* Module definitions */
+
+typedef struct conf_imodule_st CONF_IMODULE;
+typedef struct conf_module_st CONF_MODULE;
+
+/* DSO module function typedefs */
+typedef int conf_init_func(CONF_IMODULE *md, const CONF *cnf);
+typedef void conf_finish_func(CONF_IMODULE *md);
+
+#define	CONF_MFLAGS_IGNORE_ERRORS	0x1
+#define CONF_MFLAGS_IGNORE_RETURN_CODES	0x2
+#define CONF_MFLAGS_SILENT		0x4
+#define CONF_MFLAGS_NO_DSO		0x8
+#define CONF_MFLAGS_IGNORE_MISSING_FILE	0x10
+
+int CONF_set_default_method(CONF_METHOD *meth);
+void CONF_set_nconf(CONF *conf,LHASH *hash);
+LHASH *CONF_load(LHASH *conf,const char *file,long *eline);
+#ifndef OPENSSL_NO_FP_API
+LHASH *CONF_load_fp(LHASH *conf, FILE *fp,long *eline);
+#endif
+LHASH *CONF_load_bio(LHASH *conf, BIO *bp,long *eline);
+STACK_OF(CONF_VALUE) *CONF_get_section(LHASH *conf,const char *section);
+char *CONF_get_string(LHASH *conf,const char *group,const char *name);
+long CONF_get_number(LHASH *conf,const char *group,const char *name);
+void CONF_free(LHASH *conf);
+int CONF_dump_fp(LHASH *conf, FILE *out);
+int CONF_dump_bio(LHASH *conf, BIO *out);
+
+void OPENSSL_config(const char *config_name);
+void OPENSSL_no_config(void);
+
+/* New conf code.  The semantics are different from the functions above.
+   If that wasn't the case, the above functions would have been replaced */
+
+struct conf_st
+	{
+	CONF_METHOD *meth;
+	void *meth_data;
+	LHASH *data;
+	};
+
+CONF *NCONF_new(CONF_METHOD *meth);
+CONF_METHOD *NCONF_default(void);
+CONF_METHOD *NCONF_WIN32(void);
+#if 0 /* Just to give you an idea of what I have in mind */
+CONF_METHOD *NCONF_XML(void);
+#endif
+void NCONF_free(CONF *conf);
+void NCONF_free_data(CONF *conf);
+
+int NCONF_load(CONF *conf,const char *file,long *eline);
+#ifndef OPENSSL_NO_FP_API
+int NCONF_load_fp(CONF *conf, FILE *fp,long *eline);
+#endif
+int NCONF_load_bio(CONF *conf, BIO *bp,long *eline);
+STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf,const char *section);
+char *NCONF_get_string(const CONF *conf,const char *group,const char *name);
+int NCONF_get_number_e(const CONF *conf,const char *group,const char *name,
+		       long *result);
+int NCONF_dump_fp(const CONF *conf, FILE *out);
+int NCONF_dump_bio(const CONF *conf, BIO *out);
+
+#if 0 /* The following function has no error checking,
+	 and should therefore be avoided */
+long NCONF_get_number(CONF *conf,char *group,char *name);
+#else
+#define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r)
+#endif
+  
+/* Module functions */
+
+int CONF_modules_load(const CONF *cnf, const char *appname,
+		      unsigned long flags);
+int CONF_modules_load_file(const char *filename, const char *appname,
+			   unsigned long flags);
+void CONF_modules_unload(int all);
+void CONF_modules_finish(void);
+void CONF_modules_free(void);
+int CONF_module_add(const char *name, conf_init_func *ifunc,
+		    conf_finish_func *ffunc);
+
+const char *CONF_imodule_get_name(const CONF_IMODULE *md);
+const char *CONF_imodule_get_value(const CONF_IMODULE *md);
+void *CONF_imodule_get_usr_data(const CONF_IMODULE *md);
+void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data);
+CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md);
+unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md);
+void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags);
+void *CONF_module_get_usr_data(CONF_MODULE *pmod);
+void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data);
+
+char *CONF_get1_default_config_file(void);
+
+int CONF_parse_list(const char *list, int sep, int nospc,
+	int (*list_cb)(const char *elem, int len, void *usr), void *arg);
+
+void OPENSSL_load_builtin_modules(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_CONF_strings(void);
+
+/* Error codes for the CONF functions. */
+
+/* Function codes. */
+#define CONF_F_CONF_DUMP_FP				 104
+#define CONF_F_CONF_LOAD				 100
+#define CONF_F_CONF_LOAD_BIO				 102
+#define CONF_F_CONF_LOAD_FP				 103
+#define CONF_F_CONF_MODULES_LOAD			 116
+#define CONF_F_DEF_LOAD					 120
+#define CONF_F_DEF_LOAD_BIO				 121
+#define CONF_F_MODULE_INIT				 115
+#define CONF_F_MODULE_LOAD_DSO				 117
+#define CONF_F_MODULE_RUN				 118
+#define CONF_F_NCONF_DUMP_BIO				 105
+#define CONF_F_NCONF_DUMP_FP				 106
+#define CONF_F_NCONF_GET_NUMBER				 107
+#define CONF_F_NCONF_GET_NUMBER_E			 112
+#define CONF_F_NCONF_GET_SECTION			 108
+#define CONF_F_NCONF_GET_STRING				 109
+#define CONF_F_NCONF_LOAD				 113
+#define CONF_F_NCONF_LOAD_BIO				 110
+#define CONF_F_NCONF_LOAD_FP				 114
+#define CONF_F_NCONF_NEW				 111
+#define CONF_F_STR_COPY					 101
+
+/* Reason codes. */
+#define CONF_R_ERROR_LOADING_DSO			 110
+#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET		 100
+#define CONF_R_MISSING_EQUAL_SIGN			 101
+#define CONF_R_MISSING_FINISH_FUNCTION			 111
+#define CONF_R_MISSING_INIT_FUNCTION			 112
+#define CONF_R_MODULE_INITIALIZATION_ERROR		 109
+#define CONF_R_NO_CLOSE_BRACE				 102
+#define CONF_R_NO_CONF					 105
+#define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE		 106
+#define CONF_R_NO_SECTION				 107
+#define CONF_R_NO_SUCH_FILE				 114
+#define CONF_R_NO_VALUE					 108
+#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION		 103
+#define CONF_R_UNKNOWN_MODULE_NAME			 113
+#define CONF_R_VARIABLE_HAS_NO_VALUE			 104
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/conf_api.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/conf_api.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/conf_api.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,89 @@
+/* conf_api.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef  HEADER_CONF_API_H
+#define HEADER_CONF_API_H
+
+#include <openssl/lhash.h>
+#include <openssl/conf.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Up until OpenSSL 0.9.5a, this was new_section */
+CONF_VALUE *_CONF_new_section(CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was get_section */
+CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section);
+/* Up until OpenSSL 0.9.5a, this was CONF_get_section */
+STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf,
+					       const char *section);
+
+int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value);
+char *_CONF_get_string(const CONF *conf, const char *section,
+		       const char *name);
+long _CONF_get_number(const CONF *conf, const char *section, const char *name);
+
+int _CONF_new_data(CONF *conf);
+void _CONF_free_data(CONF *conf);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/crypto.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/crypto.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/crypto.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,550 @@
+/* crypto/crypto.h */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_CRYPTO_H
+#define HEADER_CRYPTO_H
+
+#include <stdlib.h>
+
+#include <openssl/e_os2.h>
+
+#ifndef OPENSSL_NO_FP_API
+#include <stdio.h>
+#endif
+
+#include <openssl/stack.h>
+#include <openssl/safestack.h>
+#include <openssl/opensslv.h>
+#include <openssl/ossl_typ.h>
+
+#ifdef CHARSET_EBCDIC
+#include <openssl/ebcdic.h>
+#endif
+
+/* Resolve problems on some operating systems with symbol names that clash
+   one way or another */
+#include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Backward compatibility to SSLeay */
+/* This is more to be used to check the correct DLL is being used
+ * in the MS world. */
+#define SSLEAY_VERSION_NUMBER	OPENSSL_VERSION_NUMBER
+#define SSLEAY_VERSION		0
+/* #define SSLEAY_OPTIONS	1 no longer supported */
+#define SSLEAY_CFLAGS		2
+#define SSLEAY_BUILT_ON		3
+#define SSLEAY_PLATFORM		4
+#define SSLEAY_DIR		5
+
+/* Already declared in ossl_typ.h */
+#if 0
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Called when a new object is created */
+typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+/* Called when an object is free()ed */
+typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+/* Called when we need to dup an object */
+typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
+					int idx, long argl, void *argp);
+#endif
+
+/* A generic structure to pass assorted data in a expandable way */
+typedef struct openssl_item_st
+	{
+	int code;
+	void *value;		/* Not used for flag attributes */
+	size_t value_size;	/* Max size of value for output, length for input */
+	size_t *value_length;	/* Returned length of value for output */
+	} OPENSSL_ITEM;
+
+
+/* When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock
+ * names in cryptlib.c
+ */
+
+#define	CRYPTO_LOCK_ERR			1
+#define	CRYPTO_LOCK_EX_DATA		2
+#define	CRYPTO_LOCK_X509		3
+#define	CRYPTO_LOCK_X509_INFO		4
+#define	CRYPTO_LOCK_X509_PKEY		5
+#define CRYPTO_LOCK_X509_CRL		6
+#define CRYPTO_LOCK_X509_REQ		7
+#define CRYPTO_LOCK_DSA			8
+#define CRYPTO_LOCK_RSA			9
+#define CRYPTO_LOCK_EVP_PKEY		10
+#define CRYPTO_LOCK_X509_STORE		11
+#define CRYPTO_LOCK_SSL_CTX		12
+#define CRYPTO_LOCK_SSL_CERT		13
+#define CRYPTO_LOCK_SSL_SESSION		14
+#define CRYPTO_LOCK_SSL_SESS_CERT	15
+#define CRYPTO_LOCK_SSL			16
+#define CRYPTO_LOCK_SSL_METHOD		17
+#define CRYPTO_LOCK_RAND		18
+#define CRYPTO_LOCK_RAND2		19
+#define CRYPTO_LOCK_MALLOC		20
+#define CRYPTO_LOCK_BIO			21
+#define CRYPTO_LOCK_GETHOSTBYNAME	22
+#define CRYPTO_LOCK_GETSERVBYNAME	23
+#define CRYPTO_LOCK_READDIR		24
+#define CRYPTO_LOCK_RSA_BLINDING	25
+#define CRYPTO_LOCK_DH			26
+#define CRYPTO_LOCK_MALLOC2		27
+#define CRYPTO_LOCK_DSO			28
+#define CRYPTO_LOCK_DYNLOCK		29
+#define CRYPTO_LOCK_ENGINE		30
+#define CRYPTO_LOCK_UI			31
+#define CRYPTO_LOCK_ECDSA               32
+#define CRYPTO_LOCK_EC			33
+#define CRYPTO_LOCK_ECDH		34
+#define CRYPTO_LOCK_BN  		35
+#define CRYPTO_LOCK_EC_PRE_COMP		36
+#define CRYPTO_LOCK_STORE		37
+#define CRYPTO_LOCK_COMP		38
+#define CRYPTO_NUM_LOCKS		39
+
+#define CRYPTO_LOCK		1
+#define CRYPTO_UNLOCK		2
+#define CRYPTO_READ		4
+#define CRYPTO_WRITE		8
+
+#ifndef OPENSSL_NO_LOCKING
+#ifndef CRYPTO_w_lock
+#define CRYPTO_w_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_w_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__)
+#define CRYPTO_r_lock(type)	\
+	CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_r_unlock(type)	\
+	CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__)
+#define CRYPTO_add(addr,amount,type)	\
+	CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__)
+#endif
+#else
+#define CRYPTO_w_lock(a)
+#define CRYPTO_w_unlock(a)
+#define CRYPTO_r_lock(a)
+#define CRYPTO_r_unlock(a)
+#define CRYPTO_add(a,b,c)	((*(a))+=(b))
+#endif
+
+/* Some applications as well as some parts of OpenSSL need to allocate
+   and deallocate locks in a dynamic fashion.  The following typedef
+   makes this possible in a type-safe manner.  */
+/* struct CRYPTO_dynlock_value has to be defined by the application. */
+typedef struct
+	{
+	int references;
+	struct CRYPTO_dynlock_value *data;
+	} CRYPTO_dynlock;
+
+
+/* The following can be used to detect memory leaks in the SSLeay library.
+ * It used, it turns on malloc checking */
+
+#define CRYPTO_MEM_CHECK_OFF	0x0	/* an enume */
+#define CRYPTO_MEM_CHECK_ON	0x1	/* a bit */
+#define CRYPTO_MEM_CHECK_ENABLE	0x2	/* a bit */
+#define CRYPTO_MEM_CHECK_DISABLE 0x3	/* an enume */
+
+/* The following are bit values to turn on or off options connected to the
+ * malloc checking functionality */
+
+/* Adds time to the memory checking information */
+#define V_CRYPTO_MDEBUG_TIME	0x1 /* a bit */
+/* Adds thread number to the memory checking information */
+#define V_CRYPTO_MDEBUG_THREAD	0x2 /* a bit */
+
+#define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD)
+
+
+/* predec of the BIO type */
+typedef struct bio_st BIO_dummy;
+
+struct crypto_ex_data_st
+	{
+	STACK *sk;
+	int dummy; /* gcc is screwing up this data structure :-( */
+	};
+
+/* This stuff is basically class callback functions
+ * The current classes are SSL_CTX, SSL, SSL_SESSION, and a few more */
+
+typedef struct crypto_ex_data_func_st
+	{
+	long argl;	/* Arbitary long */
+	void *argp;	/* Arbitary void * */
+	CRYPTO_EX_new *new_func;
+	CRYPTO_EX_free *free_func;
+	CRYPTO_EX_dup *dup_func;
+	} CRYPTO_EX_DATA_FUNCS;
+
+DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS)
+
+/* Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA
+ * entry.
+ */
+
+#define CRYPTO_EX_INDEX_BIO		0
+#define CRYPTO_EX_INDEX_SSL		1
+#define CRYPTO_EX_INDEX_SSL_CTX		2
+#define CRYPTO_EX_INDEX_SSL_SESSION	3
+#define CRYPTO_EX_INDEX_X509_STORE	4
+#define CRYPTO_EX_INDEX_X509_STORE_CTX	5
+#define CRYPTO_EX_INDEX_RSA		6
+#define CRYPTO_EX_INDEX_DSA		7
+#define CRYPTO_EX_INDEX_DH		8
+#define CRYPTO_EX_INDEX_ENGINE		9
+#define CRYPTO_EX_INDEX_X509		10
+#define CRYPTO_EX_INDEX_UI		11
+#define CRYPTO_EX_INDEX_ECDSA		12
+#define CRYPTO_EX_INDEX_ECDH		13
+#define CRYPTO_EX_INDEX_COMP		14
+#define CRYPTO_EX_INDEX_STORE		15
+
+/* Dynamically assigned indexes start from this value (don't use directly, use
+ * via CRYPTO_ex_data_new_class). */
+#define CRYPTO_EX_INDEX_USER		100
+
+
+/* This is the default callbacks, but we can have others as well:
+ * this is needed in Win32 where the application malloc and the
+ * library malloc may not be the same.
+ */
+#define CRYPTO_malloc_init()	CRYPTO_set_mem_functions(\
+	malloc, realloc, free)
+
+#if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD
+# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */
+#  define CRYPTO_MDEBUG
+# endif
+#endif
+
+/* Set standard debugging functions (not done by default
+ * unless CRYPTO_MDEBUG is defined) */
+#define CRYPTO_malloc_debug_init()	do {\
+	CRYPTO_set_mem_debug_functions(\
+		CRYPTO_dbg_malloc,\
+		CRYPTO_dbg_realloc,\
+		CRYPTO_dbg_free,\
+		CRYPTO_dbg_set_options,\
+		CRYPTO_dbg_get_options);\
+	} while(0)
+
+int CRYPTO_mem_ctrl(int mode);
+int CRYPTO_is_mem_check_on(void);
+
+/* for applications */
+#define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON)
+#define MemCheck_stop()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF)
+
+/* for library-internal use */
+#define MemCheck_on()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE)
+#define MemCheck_off()	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE)
+#define is_MemCheck_on() CRYPTO_is_mem_check_on()
+
+#define OPENSSL_malloc(num)	CRYPTO_malloc((int)num,__FILE__,__LINE__)
+#define OPENSSL_realloc(addr,num) \
+	CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__)
+#define OPENSSL_realloc_clean(addr,old_num,num) \
+	CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__)
+#define OPENSSL_remalloc(addr,num) \
+	CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__)
+#define OPENSSL_freeFunc	CRYPTO_free
+#define OPENSSL_free(addr)	CRYPTO_free(addr)
+
+#define OPENSSL_malloc_locked(num) \
+	CRYPTO_malloc_locked((int)num,__FILE__,__LINE__)
+#define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr)
+
+
+const char *SSLeay_version(int type);
+unsigned long SSLeay(void);
+
+int OPENSSL_issetugid(void);
+
+/* An opaque type representing an implementation of "ex_data" support */
+typedef struct st_CRYPTO_EX_DATA_IMPL	CRYPTO_EX_DATA_IMPL;
+/* Return an opaque pointer to the current "ex_data" implementation */
+const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void);
+/* Sets the "ex_data" implementation to be used (if it's not too late) */
+int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i);
+/* Get a new "ex_data" class, and return the corresponding "class_index" */
+int CRYPTO_ex_data_new_class(void);
+/* Within a given class, get/register a new index */
+int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp,
+		CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func,
+		CRYPTO_EX_free *free_func);
+/* Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a given
+ * class (invokes whatever per-class callbacks are applicable) */
+int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
+		CRYPTO_EX_DATA *from);
+void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad);
+/* Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular index
+ * (relative to the class type involved) */
+int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val);
+void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad,int idx);
+/* This function cleans up all "ex_data" state. It mustn't be called under
+ * potential race-conditions. */
+void CRYPTO_cleanup_all_ex_data(void);
+
+int CRYPTO_get_new_lockid(char *name);
+
+int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */
+void CRYPTO_lock(int mode, int type,const char *file,int line);
+void CRYPTO_set_locking_callback(void (*func)(int mode,int type,
+					      const char *file,int line));
+void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
+		int line);
+void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
+					      const char *file, int line));
+int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
+					  const char *file,int line);
+void CRYPTO_set_id_callback(unsigned long (*func)(void));
+unsigned long (*CRYPTO_get_id_callback(void))(void);
+unsigned long CRYPTO_thread_id(void);
+const char *CRYPTO_get_lock_name(int type);
+int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
+		    int line);
+
+int CRYPTO_get_new_dynlockid(void);
+void CRYPTO_destroy_dynlockid(int i);
+struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i);
+void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, int line));
+void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)(int mode, struct CRYPTO_dynlock_value *l, const char *file, int line));
+void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, const char *file, int line));
+struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))(const char *file,int line);
+void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, struct CRYPTO_dynlock_value *l, const char *file,int line);
+void (*CRYPTO_get_dynlock_destroy_callback(void))(struct CRYPTO_dynlock_value *l, const char *file,int line);
+
+/* CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions --
+ * call the latter last if you need different functions */
+int CRYPTO_set_mem_functions(void *(*m)(size_t),void *(*r)(void *,size_t), void (*f)(void *));
+int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*free_func)(void *));
+int CRYPTO_set_mem_ex_functions(void *(*m)(size_t,const char *,int),
+                                void *(*r)(void *,size_t,const char *,int),
+                                void (*f)(void *));
+int CRYPTO_set_locked_mem_ex_functions(void *(*m)(size_t,const char *,int),
+                                       void (*free_func)(void *));
+int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
+				   void (*r)(void *,void *,int,const char *,int,int),
+				   void (*f)(void *,int),
+				   void (*so)(long),
+				   long (*go)(void));
+void CRYPTO_get_mem_functions(void *(**m)(size_t),void *(**r)(void *, size_t), void (**f)(void *));
+void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *));
+void CRYPTO_get_mem_ex_functions(void *(**m)(size_t,const char *,int),
+                                 void *(**r)(void *, size_t,const char *,int),
+                                 void (**f)(void *));
+void CRYPTO_get_locked_mem_ex_functions(void *(**m)(size_t,const char *,int),
+                                        void (**f)(void *));
+void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
+				    void (**r)(void *,void *,int,const char *,int,int),
+				    void (**f)(void *,int),
+				    void (**so)(long),
+				    long (**go)(void));
+
+void *CRYPTO_malloc_locked(int num, const char *file, int line);
+void CRYPTO_free_locked(void *);
+void *CRYPTO_malloc(int num, const char *file, int line);
+void CRYPTO_free(void *);
+void *CRYPTO_realloc(void *addr,int num, const char *file, int line);
+void *CRYPTO_realloc_clean(void *addr,int old_num,int num,const char *file,
+			   int line);
+void *CRYPTO_remalloc(void *addr,int num, const char *file, int line);
+
+void OPENSSL_cleanse(void *ptr, size_t len);
+
+void CRYPTO_set_mem_debug_options(long bits);
+long CRYPTO_get_mem_debug_options(void);
+
+#define CRYPTO_push_info(info) \
+        CRYPTO_push_info_(info, __FILE__, __LINE__);
+int CRYPTO_push_info_(const char *info, const char *file, int line);
+int CRYPTO_pop_info(void);
+int CRYPTO_remove_all_info(void);
+
+
+/* Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro;
+ * used as default in CRYPTO_MDEBUG compilations): */
+/* The last argument has the following significance:
+ *
+ * 0:	called before the actual memory allocation has taken place
+ * 1:	called after the actual memory allocation has taken place
+ */
+void CRYPTO_dbg_malloc(void *addr,int num,const char *file,int line,int before_p);
+void CRYPTO_dbg_realloc(void *addr1,void *addr2,int num,const char *file,int line,int before_p);
+void CRYPTO_dbg_free(void *addr,int before_p);
+/* Tell the debugging code about options.  By default, the following values
+ * apply:
+ *
+ * 0:                           Clear all options.
+ * V_CRYPTO_MDEBUG_TIME (1):    Set the "Show Time" option.
+ * V_CRYPTO_MDEBUG_THREAD (2):  Set the "Show Thread Number" option.
+ * V_CRYPTO_MDEBUG_ALL (3):     1 + 2
+ */
+void CRYPTO_dbg_set_options(long bits);
+long CRYPTO_dbg_get_options(void);
+
+
+#ifndef OPENSSL_NO_FP_API
+void CRYPTO_mem_leaks_fp(FILE *);
+#endif
+void CRYPTO_mem_leaks(struct bio_st *bio);
+/* unsigned long order, char *file, int line, int num_bytes, char *addr */
+typedef void *CRYPTO_MEM_LEAK_CB(unsigned long, const char *, int, int, void *);
+void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb);
+
+/* die if we have to */
+void OpenSSLDie(const char *file,int line,const char *assertion);
+#define OPENSSL_assert(e)       (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1))
+
+unsigned long *OPENSSL_ia32cap_loc(void);
+#define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc()))
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_CRYPTO_strings(void);
+
+/* Error codes for the CRYPTO functions. */
+
+/* Function codes. */
+#define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX		 100
+#define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID		 103
+#define CRYPTO_F_CRYPTO_GET_NEW_LOCKID			 101
+#define CRYPTO_F_CRYPTO_SET_EX_DATA			 102
+#define CRYPTO_F_DEF_ADD_INDEX				 104
+#define CRYPTO_F_DEF_GET_CLASS				 105
+#define CRYPTO_F_INT_DUP_EX_DATA			 106
+#define CRYPTO_F_INT_FREE_EX_DATA			 107
+#define CRYPTO_F_INT_NEW_EX_DATA			 108
+
+/* Reason codes. */
+#define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK		 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/des.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/des.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/des.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,244 @@
+/* crypto/des/des.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_NEW_DES_H
+#define HEADER_NEW_DES_H
+
+#include <openssl/e_os2.h>	/* OPENSSL_EXTERN, OPENSSL_NO_DES,
+				   DES_LONG (via openssl/opensslconf.h */
+
+#ifdef OPENSSL_NO_DES
+#error DES is disabled.
+#endif
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char DES_cblock[8];
+typedef /* const */ unsigned char const_DES_cblock[8];
+/* With "const", gcc 2.8.1 on Solaris thinks that DES_cblock *
+ * and const_DES_cblock * are incompatible pointer types. */
+
+typedef struct DES_ks
+    {
+    union
+	{
+	DES_cblock cblock;
+	/* make sure things are correct size on machines with
+	 * 8 byte longs */
+	DES_LONG deslong[2];
+	} ks[16];
+    } DES_key_schedule;
+
+#ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT
+# ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT
+#  define OPENSSL_ENABLE_OLD_DES_SUPPORT
+# endif
+#endif
+
+#ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT
+# include <openssl/des_old.h>
+#endif
+
+#define DES_KEY_SZ 	(sizeof(DES_cblock))
+#define DES_SCHEDULE_SZ (sizeof(DES_key_schedule))
+
+#define DES_ENCRYPT	1
+#define DES_DECRYPT	0
+
+#define DES_CBC_MODE	0
+#define DES_PCBC_MODE	1
+
+#define DES_ecb2_encrypt(i,o,k1,k2,e) \
+	DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+	DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+	DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+	DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+OPENSSL_DECLARE_GLOBAL(int,DES_check_key);	/* defaults to false */
+#define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key)
+OPENSSL_DECLARE_GLOBAL(int,DES_rw_mode);	/* defaults to DES_PCBC_MODE */
+#define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode)
+
+const char *DES_options(void);
+void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
+		      DES_key_schedule *ks1,DES_key_schedule *ks2,
+		      DES_key_schedule *ks3, int enc);
+DES_LONG DES_cbc_cksum(const unsigned char *input,DES_cblock *output,
+		       long length,DES_key_schedule *schedule,
+		       const_DES_cblock *ivec);
+/* DES_cbc_encrypt does not update the IV!  Use DES_ncbc_encrypt instead. */
+void DES_cbc_encrypt(const unsigned char *input,unsigned char *output,
+		     long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		     int enc);
+void DES_ncbc_encrypt(const unsigned char *input,unsigned char *output,
+		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		      int enc);
+void DES_xcbc_encrypt(const unsigned char *input,unsigned char *output,
+		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		      const_DES_cblock *inw,const_DES_cblock *outw,int enc);
+void DES_cfb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
+		     long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		     int enc);
+void DES_ecb_encrypt(const_DES_cblock *input,DES_cblock *output,
+		     DES_key_schedule *ks,int enc);
+
+/* 	This is the DES encryption function that gets called by just about
+	every other DES routine in the library.  You should not use this
+	function except to implement 'modes' of DES.  I say this because the
+	functions that call this routine do the conversion from 'char *' to
+	long, and this needs to be done to make sure 'non-aligned' memory
+	access do not occur.  The characters are loaded 'little endian'.
+	Data is a pointer to 2 unsigned long's and ks is the
+	DES_key_schedule to use.  enc, is non zero specifies encryption,
+	zero if decryption. */
+void DES_encrypt1(DES_LONG *data,DES_key_schedule *ks, int enc);
+
+/* 	This functions is the same as DES_encrypt1() except that the DES
+	initial permutation (IP) and final permutation (FP) have been left
+	out.  As for DES_encrypt1(), you should not use this function.
+	It is used by the routines in the library that implement triple DES.
+	IP() DES_encrypt2() DES_encrypt2() DES_encrypt2() FP() is the same
+	as DES_encrypt1() DES_encrypt1() DES_encrypt1() except faster :-). */
+void DES_encrypt2(DES_LONG *data,DES_key_schedule *ks, int enc);
+
+void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1,
+		  DES_key_schedule *ks2, DES_key_schedule *ks3);
+void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, 
+			  long length,
+			  DES_key_schedule *ks1,DES_key_schedule *ks2,
+			  DES_key_schedule *ks3,DES_cblock *ivec,int enc);
+void DES_ede3_cbcm_encrypt(const unsigned char *in,unsigned char *out,
+			   long length,
+			   DES_key_schedule *ks1,DES_key_schedule *ks2,
+			   DES_key_schedule *ks3,
+			   DES_cblock *ivec1,DES_cblock *ivec2,
+			   int enc);
+void DES_ede3_cfb64_encrypt(const unsigned char *in,unsigned char *out,
+			    long length,DES_key_schedule *ks1,
+			    DES_key_schedule *ks2,DES_key_schedule *ks3,
+			    DES_cblock *ivec,int *num,int enc);
+void DES_ede3_cfb_encrypt(const unsigned char *in,unsigned char *out,
+			  int numbits,long length,DES_key_schedule *ks1,
+			  DES_key_schedule *ks2,DES_key_schedule *ks3,
+			  DES_cblock *ivec,int enc);
+void DES_ede3_ofb64_encrypt(const unsigned char *in,unsigned char *out,
+			    long length,DES_key_schedule *ks1,
+			    DES_key_schedule *ks2,DES_key_schedule *ks3,
+			    DES_cblock *ivec,int *num);
+
+void DES_xwhite_in2out(const_DES_cblock *DES_key,const_DES_cblock *in_white,
+		       DES_cblock *out_white);
+
+int DES_enc_read(int fd,void *buf,int len,DES_key_schedule *sched,
+		 DES_cblock *iv);
+int DES_enc_write(int fd,const void *buf,int len,DES_key_schedule *sched,
+		  DES_cblock *iv);
+char *DES_fcrypt(const char *buf,const char *salt, char *ret);
+char *DES_crypt(const char *buf,const char *salt);
+void DES_ofb_encrypt(const unsigned char *in,unsigned char *out,int numbits,
+		     long length,DES_key_schedule *schedule,DES_cblock *ivec);
+void DES_pcbc_encrypt(const unsigned char *input,unsigned char *output,
+		      long length,DES_key_schedule *schedule,DES_cblock *ivec,
+		      int enc);
+DES_LONG DES_quad_cksum(const unsigned char *input,DES_cblock output[],
+			long length,int out_count,DES_cblock *seed);
+int DES_random_key(DES_cblock *ret);
+void DES_set_odd_parity(DES_cblock *key);
+int DES_check_key_parity(const_DES_cblock *key);
+int DES_is_weak_key(const_DES_cblock *key);
+/* DES_set_key (= set_key = DES_key_sched = key_sched) calls
+ * DES_set_key_checked if global variable DES_check_key is set,
+ * DES_set_key_unchecked otherwise. */
+int DES_set_key(const_DES_cblock *key,DES_key_schedule *schedule);
+int DES_key_sched(const_DES_cblock *key,DES_key_schedule *schedule);
+int DES_set_key_checked(const_DES_cblock *key,DES_key_schedule *schedule);
+void DES_set_key_unchecked(const_DES_cblock *key,DES_key_schedule *schedule);
+void DES_string_to_key(const char *str,DES_cblock *key);
+void DES_string_to_2keys(const char *str,DES_cblock *key1,DES_cblock *key2);
+void DES_cfb64_encrypt(const unsigned char *in,unsigned char *out,long length,
+		       DES_key_schedule *schedule,DES_cblock *ivec,int *num,
+		       int enc);
+void DES_ofb64_encrypt(const unsigned char *in,unsigned char *out,long length,
+		       DES_key_schedule *schedule,DES_cblock *ivec,int *num);
+
+int DES_read_password(DES_cblock *key, const char *prompt, int verify);
+int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, const char *prompt,
+	int verify);
+
+#define DES_fixup_key_parity DES_set_odd_parity
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/des_old.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/des_old.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/des_old.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,441 @@
+/* crypto/des/des_old.h -*- mode:C; c-file-style: "eay" -*- */
+
+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ * The function names in here are deprecated and are only present to
+ * provide an interface compatible with openssl 0.9.6 and older as
+ * well as libdes.  OpenSSL now provides functions where "des_" has
+ * been replaced with "DES_" in the names, to make it possible to
+ * make incompatible changes that are needed for C type security and
+ * other stuff.
+ *
+ * This include files has two compatibility modes:
+ *
+ *   - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API
+ *     that is compatible with libdes and SSLeay.
+ *   - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an
+ *     API that is compatible with OpenSSL 0.9.5x to 0.9.6x.
+ *
+ * Note that these modes break earlier snapshots of OpenSSL, where
+ * libdes compatibility was the only available mode or (later on) the
+ * prefered compatibility mode.  However, after much consideration
+ * (and more or less violent discussions with external parties), it
+ * was concluded that OpenSSL should be compatible with earlier versions
+ * of itself before anything else.  Also, in all honesty, libdes is
+ * an old beast that shouldn't really be used any more.
+ *
+ * Please consider starting to use the DES_ functions rather than the
+ * des_ ones.  The des_ functions will disappear completely before
+ * OpenSSL 1.0!
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ */
+
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DES_H
+#define HEADER_DES_H
+
+#include <openssl/e_os2.h>	/* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */
+
+#ifdef OPENSSL_NO_DES
+#error DES is disabled.
+#endif
+
+#ifndef HEADER_NEW_DES_H
+#error You must include des.h, not des_old.h directly.
+#endif
+
+#ifdef _KERBEROS_DES_H
+#error <openssl/des_old.h> replaces <kerberos/des.h>.
+#endif
+
+#include <openssl/symhacks.h>
+
+#ifdef OPENSSL_BUILD_SHLIBCRYPTO
+# undef OPENSSL_EXTERN
+# define OPENSSL_EXTERN OPENSSL_EXPORT
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef unsigned char _ossl_old_des_cblock[8];
+typedef struct _ossl_old_des_ks_struct
+	{
+	union	{
+		_ossl_old_des_cblock _;
+		/* make sure things are correct size on machines with
+		 * 8 byte longs */
+		DES_LONG pad[2];
+		} ks;
+	} _ossl_old_des_key_schedule[16];
+
+#ifndef OPENSSL_DES_LIBDES_COMPATIBILITY
+#define des_cblock DES_cblock
+#define const_des_cblock const_DES_cblock
+#define des_key_schedule DES_key_schedule
+#define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
+	DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e))
+#define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
+	DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e))
+#define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\
+	DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e))
+#define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
+	DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e))
+#define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
+	DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n))
+#define des_options()\
+	DES_options()
+#define des_cbc_cksum(i,o,l,k,iv)\
+	DES_cbc_cksum((i),(o),(l),&(k),(iv))
+#define des_cbc_encrypt(i,o,l,k,iv,e)\
+	DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#define des_ncbc_encrypt(i,o,l,k,iv,e)\
+	DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
+	DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e))
+#define des_cfb_encrypt(i,o,n,l,k,iv,e)\
+	DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e))
+#define des_ecb_encrypt(i,o,k,e)\
+	DES_ecb_encrypt((i),(o),&(k),(e))
+#define des_encrypt1(d,k,e)\
+	DES_encrypt1((d),&(k),(e))
+#define des_encrypt2(d,k,e)\
+	DES_encrypt2((d),&(k),(e))
+#define des_encrypt3(d,k1,k2,k3)\
+	DES_encrypt3((d),&(k1),&(k2),&(k3))
+#define des_decrypt3(d,k1,k2,k3)\
+	DES_decrypt3((d),&(k1),&(k2),&(k3))
+#define des_xwhite_in2out(k,i,o)\
+	DES_xwhite_in2out((k),(i),(o))
+#define des_enc_read(f,b,l,k,iv)\
+	DES_enc_read((f),(b),(l),&(k),(iv))
+#define des_enc_write(f,b,l,k,iv)\
+	DES_enc_write((f),(b),(l),&(k),(iv))
+#define des_fcrypt(b,s,r)\
+	DES_fcrypt((b),(s),(r))
+#if 0
+#define des_crypt(b,s)\
+	DES_crypt((b),(s))
+#if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__)
+#define crypt(b,s)\
+	DES_crypt((b),(s))
+#endif
+#endif
+#define des_ofb_encrypt(i,o,n,l,k,iv)\
+	DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv))
+#define des_pcbc_encrypt(i,o,l,k,iv,e)\
+	DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e))
+#define des_quad_cksum(i,o,l,c,s)\
+	DES_quad_cksum((i),(o),(l),(c),(s))
+#define des_random_seed(k)\
+	_ossl_096_des_random_seed((k))
+#define des_random_key(r)\
+	DES_random_key((r))
+#define des_read_password(k,p,v) \
+	DES_read_password((k),(p),(v))
+#define des_read_2passwords(k1,k2,p,v) \
+	DES_read_2passwords((k1),(k2),(p),(v))
+#define des_set_odd_parity(k)\
+	DES_set_odd_parity((k))
+#define des_check_key_parity(k)\
+	DES_check_key_parity((k))
+#define des_is_weak_key(k)\
+	DES_is_weak_key((k))
+#define des_set_key(k,ks)\
+	DES_set_key((k),&(ks))
+#define des_key_sched(k,ks)\
+	DES_key_sched((k),&(ks))
+#define des_set_key_checked(k,ks)\
+	DES_set_key_checked((k),&(ks))
+#define des_set_key_unchecked(k,ks)\
+	DES_set_key_unchecked((k),&(ks))
+#define des_string_to_key(s,k)\
+	DES_string_to_key((s),(k))
+#define des_string_to_2keys(s,k1,k2)\
+	DES_string_to_2keys((s),(k1),(k2))
+#define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
+	DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e))
+#define des_ofb64_encrypt(i,o,l,ks,iv,n)\
+	DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n))
+		
+
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#define des_check_key DES_check_key
+#define des_rw_mode DES_rw_mode
+#else /* libdes compatibility */
+/* Map all symbol names to _ossl_old_des_* form, so we avoid all
+   clashes with libdes */
+#define des_cblock _ossl_old_des_cblock
+#define des_key_schedule _ossl_old_des_key_schedule
+#define des_ecb3_encrypt(i,o,k1,k2,k3,e)\
+	_ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e))
+#define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\
+	_ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e))
+#define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\
+	_ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e))
+#define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\
+	_ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n))
+#define des_options()\
+	_ossl_old_des_options()
+#define des_cbc_cksum(i,o,l,k,iv)\
+	_ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv))
+#define des_cbc_encrypt(i,o,l,k,iv,e)\
+	_ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e))
+#define des_ncbc_encrypt(i,o,l,k,iv,e)\
+	_ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e))
+#define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\
+	_ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e))
+#define des_cfb_encrypt(i,o,n,l,k,iv,e)\
+	_ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e))
+#define des_ecb_encrypt(i,o,k,e)\
+	_ossl_old_des_ecb_encrypt((i),(o),(k),(e))
+#define des_encrypt(d,k,e)\
+	_ossl_old_des_encrypt((d),(k),(e))
+#define des_encrypt2(d,k,e)\
+	_ossl_old_des_encrypt2((d),(k),(e))
+#define des_encrypt3(d,k1,k2,k3)\
+	_ossl_old_des_encrypt3((d),(k1),(k2),(k3))
+#define des_decrypt3(d,k1,k2,k3)\
+	_ossl_old_des_decrypt3((d),(k1),(k2),(k3))
+#define des_xwhite_in2out(k,i,o)\
+	_ossl_old_des_xwhite_in2out((k),(i),(o))
+#define des_enc_read(f,b,l,k,iv)\
+	_ossl_old_des_enc_read((f),(b),(l),(k),(iv))
+#define des_enc_write(f,b,l,k,iv)\
+	_ossl_old_des_enc_write((f),(b),(l),(k),(iv))
+#define des_fcrypt(b,s,r)\
+	_ossl_old_des_fcrypt((b),(s),(r))
+#define des_crypt(b,s)\
+	_ossl_old_des_crypt((b),(s))
+#if 0
+#define crypt(b,s)\
+	_ossl_old_crypt((b),(s))
+#endif
+#define des_ofb_encrypt(i,o,n,l,k,iv)\
+	_ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv))
+#define des_pcbc_encrypt(i,o,l,k,iv,e)\
+	_ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e))
+#define des_quad_cksum(i,o,l,c,s)\
+	_ossl_old_des_quad_cksum((i),(o),(l),(c),(s))
+#define des_random_seed(k)\
+	_ossl_old_des_random_seed((k))
+#define des_random_key(r)\
+	_ossl_old_des_random_key((r))
+#define des_read_password(k,p,v) \
+	_ossl_old_des_read_password((k),(p),(v))
+#define des_read_2passwords(k1,k2,p,v) \
+	_ossl_old_des_read_2passwords((k1),(k2),(p),(v))
+#define des_set_odd_parity(k)\
+	_ossl_old_des_set_odd_parity((k))
+#define des_is_weak_key(k)\
+	_ossl_old_des_is_weak_key((k))
+#define des_set_key(k,ks)\
+	_ossl_old_des_set_key((k),(ks))
+#define des_key_sched(k,ks)\
+	_ossl_old_des_key_sched((k),(ks))
+#define des_string_to_key(s,k)\
+	_ossl_old_des_string_to_key((s),(k))
+#define des_string_to_2keys(s,k1,k2)\
+	_ossl_old_des_string_to_2keys((s),(k1),(k2))
+#define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\
+	_ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e))
+#define des_ofb64_encrypt(i,o,l,ks,iv,n)\
+	_ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n))
+		
+
+#define des_ecb2_encrypt(i,o,k1,k2,e) \
+	des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
+
+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
+	des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
+
+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
+	des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
+
+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
+	des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
+
+#define des_check_key DES_check_key
+#define des_rw_mode DES_rw_mode
+#endif
+
+const char *_ossl_old_des_options(void);
+void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	_ossl_old_des_key_schedule ks1,_ossl_old_des_key_schedule ks2,
+	_ossl_old_des_key_schedule ks3, int enc);
+DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec);
+void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,
+	_ossl_old_des_cblock *inw,_ossl_old_des_cblock *outw,int enc);
+void _ossl_old_des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
+	long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	_ossl_old_des_key_schedule ks,int enc);
+void _ossl_old_des_encrypt(DES_LONG *data,_ossl_old_des_key_schedule ks, int enc);
+void _ossl_old_des_encrypt2(DES_LONG *data,_ossl_old_des_key_schedule ks, int enc);
+void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
+	_ossl_old_des_key_schedule ks2, _ossl_old_des_key_schedule ks3);
+void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1,
+	_ossl_old_des_key_schedule ks2, _ossl_old_des_key_schedule ks3);
+void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, _ossl_old_des_cblock *output, 
+	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2, 
+	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int enc);
+void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
+	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2,
+	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num, int enc);
+void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
+	long length, _ossl_old_des_key_schedule ks1, _ossl_old_des_key_schedule ks2,
+	_ossl_old_des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num);
+
+void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), _ossl_old_des_cblock (*in_white),
+	_ossl_old_des_cblock (*out_white));
+
+int _ossl_old_des_enc_read(int fd,char *buf,int len,_ossl_old_des_key_schedule sched,
+	_ossl_old_des_cblock *iv);
+int _ossl_old_des_enc_write(int fd,char *buf,int len,_ossl_old_des_key_schedule sched,
+	_ossl_old_des_cblock *iv);
+char *_ossl_old_des_fcrypt(const char *buf,const char *salt, char *ret);
+char *_ossl_old_des_crypt(const char *buf,const char *salt);
+#if !defined(PERL5) && !defined(NeXT)
+char *_ossl_old_crypt(const char *buf,const char *salt);
+#endif
+void _ossl_old_des_ofb_encrypt(unsigned char *in,unsigned char *out,
+	int numbits,long length,_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec);
+void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,long length,
+	_ossl_old_des_key_schedule schedule,_ossl_old_des_cblock *ivec,int enc);
+DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input,_ossl_old_des_cblock *output,
+	long length,int out_count,_ossl_old_des_cblock *seed);
+void _ossl_old_des_random_seed(_ossl_old_des_cblock key);
+void _ossl_old_des_random_key(_ossl_old_des_cblock ret);
+int _ossl_old_des_read_password(_ossl_old_des_cblock *key,const char *prompt,int verify);
+int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2,
+	const char *prompt,int verify);
+void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key);
+int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key);
+int _ossl_old_des_set_key(_ossl_old_des_cblock *key,_ossl_old_des_key_schedule schedule);
+int _ossl_old_des_key_sched(_ossl_old_des_cblock *key,_ossl_old_des_key_schedule schedule);
+void _ossl_old_des_string_to_key(char *str,_ossl_old_des_cblock *key);
+void _ossl_old_des_string_to_2keys(char *str,_ossl_old_des_cblock *key1,_ossl_old_des_cblock *key2);
+void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	_ossl_old_des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num, int enc);
+void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
+	_ossl_old_des_key_schedule schedule, _ossl_old_des_cblock *ivec, int *num);
+
+void _ossl_096_des_random_seed(des_cblock *key);
+
+/* The following definitions provide compatibility with the MIT Kerberos
+ * library. The _ossl_old_des_key_schedule structure is not binary compatible. */
+
+#define _KERBEROS_DES_H
+
+#define KRBDES_ENCRYPT DES_ENCRYPT
+#define KRBDES_DECRYPT DES_DECRYPT
+
+#ifdef KERBEROS
+#  define ENCRYPT DES_ENCRYPT
+#  define DECRYPT DES_DECRYPT
+#endif
+
+#ifndef NCOMPAT
+#  define C_Block des_cblock
+#  define Key_schedule des_key_schedule
+#  define KEY_SZ DES_KEY_SZ
+#  define string_to_key des_string_to_key
+#  define read_pw_string des_read_pw_string
+#  define random_key des_random_key
+#  define pcbc_encrypt des_pcbc_encrypt
+#  define set_key des_set_key
+#  define key_sched des_key_sched
+#  define ecb_encrypt des_ecb_encrypt
+#  define cbc_encrypt des_cbc_encrypt
+#  define ncbc_encrypt des_ncbc_encrypt
+#  define xcbc_encrypt des_xcbc_encrypt
+#  define cbc_cksum des_cbc_cksum
+#  define quad_cksum des_quad_cksum
+#  define check_parity des_check_key_parity
+#endif
+
+#define des_fixup_key_parity DES_fixup_key_parity
+
+#ifdef  __cplusplus
+}
+#endif
+
+/* for DES_read_pw_string et al */
+#include <openssl/ui_compat.h>
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dh.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dh.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dh.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,223 @@
+/* crypto/dh/dh.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_DH_H
+#define HEADER_DH_H
+
+#include <openssl/e_os2.h>
+
+#ifdef OPENSSL_NO_DH
+#error DH is disabled.
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+	
+#define DH_FLAG_CACHE_MONT_P     0x01
+#define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH
+                                       * implementation now uses constant time
+                                       * modular exponentiation for secret exponents
+                                       * by default. This flag causes the
+                                       * faster variable sliding window method to
+                                       * be used for all exponents.
+                                       */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dh_st DH; */
+/* typedef struct dh_method DH_METHOD; */
+
+struct dh_method
+	{
+	const char *name;
+	/* Methods here */
+	int (*generate_key)(DH *dh);
+	int (*compute_key)(unsigned char *key,const BIGNUM *pub_key,DH *dh);
+	int (*bn_mod_exp)(const DH *dh, BIGNUM *r, const BIGNUM *a,
+				const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx,
+				BN_MONT_CTX *m_ctx); /* Can be null */
+
+	int (*init)(DH *dh);
+	int (*finish)(DH *dh);
+	int flags;
+	char *app_data;
+	/* If this is non-NULL, it will be used to generate parameters */
+	int (*generate_params)(DH *dh, int prime_len, int generator, BN_GENCB *cb);
+	};
+
+struct dh_st
+	{
+	/* This first argument is used to pick up errors when
+	 * a DH is passed instead of a EVP_PKEY */
+	int pad;
+	int version;
+	BIGNUM *p;
+	BIGNUM *g;
+	long length; /* optional */
+	BIGNUM *pub_key;	/* g^x */
+	BIGNUM *priv_key;	/* x */
+
+	int flags;
+	BN_MONT_CTX *method_mont_p;
+	/* Place holders if we want to do X9.42 DH */
+	BIGNUM *q;
+	BIGNUM *j;
+	unsigned char *seed;
+	int seedlen;
+	BIGNUM *counter;
+
+	int references;
+	CRYPTO_EX_DATA ex_data;
+	const DH_METHOD *meth;
+	ENGINE *engine;
+	};
+
+#define DH_GENERATOR_2		2
+/* #define DH_GENERATOR_3	3 */
+#define DH_GENERATOR_5		5
+
+/* DH_check error codes */
+#define DH_CHECK_P_NOT_PRIME		0x01
+#define DH_CHECK_P_NOT_SAFE_PRIME	0x02
+#define DH_UNABLE_TO_CHECK_GENERATOR	0x04
+#define DH_NOT_SUITABLE_GENERATOR	0x08
+
+/* primes p where (p-1)/2 is prime too are called "safe"; we define
+   this for backward compatibility: */
+#define DH_CHECK_P_NOT_STRONG_PRIME	DH_CHECK_P_NOT_SAFE_PRIME
+
+#define DHparams_dup(x) ASN1_dup_of_const(DH,i2d_DHparams,d2i_DHparams,x)
+#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+		(char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
+#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
+		(unsigned char *)(x))
+#define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
+#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+
+const DH_METHOD *DH_OpenSSL(void);
+
+void DH_set_default_method(const DH_METHOD *meth);
+const DH_METHOD *DH_get_default_method(void);
+int DH_set_method(DH *dh, const DH_METHOD *meth);
+DH *DH_new_method(ENGINE *engine);
+
+DH *	DH_new(void);
+void	DH_free(DH *dh);
+int	DH_up_ref(DH *dh);
+int	DH_size(const DH *dh);
+int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DH_set_ex_data(DH *d, int idx, void *arg);
+void *DH_get_ex_data(DH *d, int idx);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
+DH *	DH_generate_parameters(int prime_len,int generator,
+		void (*callback)(int,int,void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int	DH_generate_parameters_ex(DH *dh, int prime_len,int generator, BN_GENCB *cb);
+
+int	DH_check(const DH *dh,int *codes);
+int	DH_generate_key(DH *dh);
+int	DH_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh);
+DH *	d2i_DHparams(DH **a,const unsigned char **pp, long length);
+int	i2d_DHparams(const DH *a,unsigned char **pp);
+#ifndef OPENSSL_NO_FP_API
+int	DHparams_print_fp(FILE *fp, const DH *x);
+#endif
+#ifndef OPENSSL_NO_BIO
+int	DHparams_print(BIO *bp, const DH *x);
+#else
+int	DHparams_print(char *bp, const DH *x);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DH_strings(void);
+
+/* Error codes for the DH functions. */
+
+/* Function codes. */
+#define DH_F_COMPUTE_KEY				 102
+#define DH_F_DHPARAMS_PRINT				 100
+#define DH_F_DHPARAMS_PRINT_FP				 101
+#define DH_F_DH_BUILTIN_GENPARAMS			 106
+#define DH_F_DH_NEW_METHOD				 105
+#define DH_F_GENERATE_KEY				 103
+#define DH_F_GENERATE_PARAMETERS			 104
+
+/* Reason codes. */
+#define DH_R_BAD_GENERATOR				 101
+#define DH_R_NO_PRIVATE_VALUE				 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dsa.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dsa.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dsa.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,279 @@
+/* crypto/dsa/dsa.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/*
+ * The DSS routines are based on patches supplied by
+ * Steven Schoch <schoch@sheba.arc.nasa.gov>.  He basically did the
+ * work and I have just tweaked them a little to fit into my
+ * stylistic vision for SSLeay :-) */
+
+#ifndef HEADER_DSA_H
+#define HEADER_DSA_H
+
+#include <openssl/e_os2.h>
+
+#ifdef OPENSSL_NO_DSA
+#error DSA is disabled.
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/crypto.h>
+#include <openssl/ossl_typ.h>
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_DH
+# include <openssl/dh.h>
+#endif
+#endif
+
+#define DSA_FLAG_CACHE_MONT_P	0x01
+#define DSA_FLAG_NO_EXP_CONSTTIME       0x02 /* new with 0.9.7h; the built-in DSA
+                                              * implementation now uses constant time
+                                              * modular exponentiation for secret exponents
+                                              * by default. This flag causes the
+                                              * faster variable sliding window method to
+                                              * be used for all exponents.
+                                              */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct dsa_st DSA; */
+/* typedef struct dsa_method DSA_METHOD; */
+
+typedef struct DSA_SIG_st
+	{
+	BIGNUM *r;
+	BIGNUM *s;
+	} DSA_SIG;
+
+struct dsa_method
+	{
+	const char *name;
+	DSA_SIG * (*dsa_do_sign)(const unsigned char *dgst, int dlen, DSA *dsa);
+	int (*dsa_sign_setup)(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
+								BIGNUM **rp);
+	int (*dsa_do_verify)(const unsigned char *dgst, int dgst_len,
+							DSA_SIG *sig, DSA *dsa);
+	int (*dsa_mod_exp)(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1,
+			BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx,
+			BN_MONT_CTX *in_mont);
+	int (*bn_mod_exp)(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+				const BIGNUM *m, BN_CTX *ctx,
+				BN_MONT_CTX *m_ctx); /* Can be null */
+	int (*init)(DSA *dsa);
+	int (*finish)(DSA *dsa);
+	int flags;
+	char *app_data;
+	/* If this is non-NULL, it is used to generate DSA parameters */
+	int (*dsa_paramgen)(DSA *dsa, int bits,
+			unsigned char *seed, int seed_len,
+			int *counter_ret, unsigned long *h_ret,
+			BN_GENCB *cb);
+	/* If this is non-NULL, it is used to generate DSA keys */
+	int (*dsa_keygen)(DSA *dsa);
+	};
+
+struct dsa_st
+	{
+	/* This first variable is used to pick up errors where
+	 * a DSA is passed instead of of a EVP_PKEY */
+	int pad;
+	long version;
+	int write_params;
+	BIGNUM *p;
+	BIGNUM *q;	/* == 20 */
+	BIGNUM *g;
+
+	BIGNUM *pub_key;  /* y public key */
+	BIGNUM *priv_key; /* x private key */
+
+	BIGNUM *kinv;	/* Signing pre-calc */
+	BIGNUM *r;	/* Signing pre-calc */
+
+	int flags;
+	/* Normally used to cache montgomery values */
+	BN_MONT_CTX *method_mont_p;
+	int references;
+	CRYPTO_EX_DATA ex_data;
+	const DSA_METHOD *meth;
+	/* functional reference if 'meth' is ENGINE-provided */
+	ENGINE *engine;
+	};
+
+#define DSAparams_dup(x) ASN1_dup_of_const(DSA,i2d_DSAparams,d2i_DSAparams,x)
+#define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \
+		(char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x))
+#define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \
+		(unsigned char *)(x))
+#define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x)
+#define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x)
+
+
+DSA_SIG * DSA_SIG_new(void);
+void	DSA_SIG_free(DSA_SIG *a);
+int	i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp);
+DSA_SIG * d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length);
+
+DSA_SIG * DSA_do_sign(const unsigned char *dgst,int dlen,DSA *dsa);
+int	DSA_do_verify(const unsigned char *dgst,int dgst_len,
+		      DSA_SIG *sig,DSA *dsa);
+
+const DSA_METHOD *DSA_OpenSSL(void);
+
+void	DSA_set_default_method(const DSA_METHOD *);
+const DSA_METHOD *DSA_get_default_method(void);
+int	DSA_set_method(DSA *dsa, const DSA_METHOD *);
+
+DSA *	DSA_new(void);
+DSA *	DSA_new_method(ENGINE *engine);
+void	DSA_free (DSA *r);
+/* "up" the DSA object's reference count */
+int	DSA_up_ref(DSA *r);
+int	DSA_size(const DSA *);
+	/* next 4 return -1 on error */
+int	DSA_sign_setup( DSA *dsa,BN_CTX *ctx_in,BIGNUM **kinvp,BIGNUM **rp);
+int	DSA_sign(int type,const unsigned char *dgst,int dlen,
+		unsigned char *sig, unsigned int *siglen, DSA *dsa);
+int	DSA_verify(int type,const unsigned char *dgst,int dgst_len,
+		const unsigned char *sigbuf, int siglen, DSA *dsa);
+int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int DSA_set_ex_data(DSA *d, int idx, void *arg);
+void *DSA_get_ex_data(DSA *d, int idx);
+
+DSA *	d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length);
+DSA *	d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length);
+DSA * 	d2i_DSAparams(DSA **a, const unsigned char **pp, long length);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
+DSA *	DSA_generate_parameters(int bits,
+		unsigned char *seed,int seed_len,
+		int *counter_ret, unsigned long *h_ret,void
+		(*callback)(int, int, void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int	DSA_generate_parameters_ex(DSA *dsa, int bits,
+		unsigned char *seed,int seed_len,
+		int *counter_ret, unsigned long *h_ret, BN_GENCB *cb);
+
+int	DSA_generate_key(DSA *a);
+int	i2d_DSAPublicKey(const DSA *a, unsigned char **pp);
+int 	i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
+int	i2d_DSAparams(const DSA *a,unsigned char **pp);
+
+#ifndef OPENSSL_NO_BIO
+int	DSAparams_print(BIO *bp, const DSA *x);
+int	DSA_print(BIO *bp, const DSA *x, int off);
+#endif
+#ifndef OPENSSL_NO_FP_API
+int	DSAparams_print_fp(FILE *fp, const DSA *x);
+int	DSA_print_fp(FILE *bp, const DSA *x, int off);
+#endif
+
+#define DSS_prime_checks 50
+/* Primality test according to FIPS PUB 186[-1], Appendix 2.1:
+ * 50 rounds of Rabin-Miller */
+#define DSA_is_prime(n, callback, cb_arg) \
+	BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg)
+
+#ifndef OPENSSL_NO_DH
+/* Convert DSA structure (key or just parameters) into DH structure
+ * (be careful to avoid small subgroup attacks when using this!) */
+DH *DSA_dup_DH(const DSA *r);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DSA_strings(void);
+
+/* Error codes for the DSA functions. */
+
+/* Function codes. */
+#define DSA_F_D2I_DSA_SIG				 110
+#define DSA_F_DSAPARAMS_PRINT				 100
+#define DSA_F_DSAPARAMS_PRINT_FP			 101
+#define DSA_F_DSA_DO_SIGN				 112
+#define DSA_F_DSA_DO_VERIFY				 113
+#define DSA_F_DSA_NEW_METHOD				 103
+#define DSA_F_DSA_PRINT					 104
+#define DSA_F_DSA_PRINT_FP				 105
+#define DSA_F_DSA_SIGN					 106
+#define DSA_F_DSA_SIGN_SETUP				 107
+#define DSA_F_DSA_SIG_NEW				 109
+#define DSA_F_DSA_VERIFY				 108
+#define DSA_F_I2D_DSA_SIG				 111
+#define DSA_F_SIG_CB					 114
+
+/* Reason codes. */
+#define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 100
+#define DSA_R_MISSING_PARAMETERS			 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dso.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dso.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dso.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,368 @@
+/* dso.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DSO_H
+#define HEADER_DSO_H
+
+#include <openssl/crypto.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* These values are used as commands to DSO_ctrl() */
+#define DSO_CTRL_GET_FLAGS	1
+#define DSO_CTRL_SET_FLAGS	2
+#define DSO_CTRL_OR_FLAGS	3
+
+/* By default, DSO_load() will translate the provided filename into a form
+ * typical for the platform (more specifically the DSO_METHOD) using the
+ * dso_name_converter function of the method. Eg. win32 will transform "blah"
+ * into "blah.dll", and dlfcn will transform it into "libblah.so". The
+ * behaviour can be overriden by setting the name_converter callback in the DSO
+ * object (using DSO_set_name_converter()). This callback could even utilise
+ * the DSO_METHOD's converter too if it only wants to override behaviour for
+ * one or two possible DSO methods. However, the following flag can be set in a
+ * DSO to prevent *any* native name-translation at all - eg. if the caller has
+ * prompted the user for a path to a driver library so the filename should be
+ * interpreted as-is. */
+#define DSO_FLAG_NO_NAME_TRANSLATION		0x01
+/* An extra flag to give if only the extension should be added as
+ * translation.  This is obviously only of importance on Unix and
+ * other operating systems where the translation also may prefix
+ * the name with something, like 'lib', and ignored everywhere else.
+ * This flag is also ignored if DSO_FLAG_NO_NAME_TRANSLATION is used
+ * at the same time. */
+#define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY	0x02
+
+/* The following flag controls the translation of symbol names to upper
+ * case.  This is currently only being implemented for OpenVMS.
+ */
+#define DSO_FLAG_UPCASE_SYMBOL			0x10
+
+/* This flag loads the library with public symbols.
+ * Meaning: The exported symbols of this library are public
+ * to all libraries loaded after this library.
+ * At the moment only implemented in unix.
+ */
+#define DSO_FLAG_GLOBAL_SYMBOLS			0x20
+
+
+typedef void (*DSO_FUNC_TYPE)(void);
+
+typedef struct dso_st DSO;
+
+/* The function prototype used for method functions (or caller-provided
+ * callbacks) that transform filenames. They are passed a DSO structure pointer
+ * (or NULL if they are to be used independantly of a DSO object) and a
+ * filename to transform. They should either return NULL (if there is an error
+ * condition) or a newly allocated string containing the transformed form that
+ * the caller will need to free with OPENSSL_free() when done. */
+typedef char* (*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *);
+/* The function prototype used for method functions (or caller-provided
+ * callbacks) that merge two file specifications. They are passed a
+ * DSO structure pointer (or NULL if they are to be used independantly of
+ * a DSO object) and two file specifications to merge. They should
+ * either return NULL (if there is an error condition) or a newly allocated
+ * string containing the result of merging that the caller will need
+ * to free with OPENSSL_free() when done.
+ * Here, merging means that bits and pieces are taken from each of the
+ * file specifications and added together in whatever fashion that is
+ * sensible for the DSO method in question.  The only rule that really
+ * applies is that if the two specification contain pieces of the same
+ * type, the copy from the string string takes priority.  One could see
+ * it as the first specification is the one given by the user and the
+ * second being a bunch of defaults to add on if they're missing in the
+ * first. */
+typedef char* (*DSO_MERGER_FUNC)(DSO *, const char *, const char *);
+
+typedef struct dso_meth_st
+	{
+	const char *name;
+	/* Loads a shared library, NB: new DSO_METHODs must ensure that a
+	 * successful load populates the loaded_filename field, and likewise a
+	 * successful unload OPENSSL_frees and NULLs it out. */
+	int (*dso_load)(DSO *dso);
+	/* Unloads a shared library */
+	int (*dso_unload)(DSO *dso);
+	/* Binds a variable */
+	void *(*dso_bind_var)(DSO *dso, const char *symname);
+	/* Binds a function - assumes a return type of DSO_FUNC_TYPE.
+	 * This should be cast to the real function prototype by the
+	 * caller. Platforms that don't have compatible representations
+	 * for different prototypes (this is possible within ANSI C)
+	 * are highly unlikely to have shared libraries at all, let
+	 * alone a DSO_METHOD implemented for them. */
+	DSO_FUNC_TYPE (*dso_bind_func)(DSO *dso, const char *symname);
+
+/* I don't think this would actually be used in any circumstances. */
+#if 0
+	/* Unbinds a variable */
+	int (*dso_unbind_var)(DSO *dso, char *symname, void *symptr);
+	/* Unbinds a function */
+	int (*dso_unbind_func)(DSO *dso, char *symname, DSO_FUNC_TYPE symptr);
+#endif
+	/* The generic (yuck) "ctrl()" function. NB: Negative return
+	 * values (rather than zero) indicate errors. */
+	long (*dso_ctrl)(DSO *dso, int cmd, long larg, void *parg);
+	/* The default DSO_METHOD-specific function for converting filenames to
+	 * a canonical native form. */
+	DSO_NAME_CONVERTER_FUNC dso_name_converter;
+	/* The default DSO_METHOD-specific function for converting filenames to
+	 * a canonical native form. */
+	DSO_MERGER_FUNC dso_merger;
+
+	/* [De]Initialisation handlers. */
+	int (*init)(DSO *dso);
+	int (*finish)(DSO *dso);
+	} DSO_METHOD;
+
+/**********************************************************************/
+/* The low-level handle type used to refer to a loaded shared library */
+
+struct dso_st
+	{
+	DSO_METHOD *meth;
+	/* Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS
+	 * doesn't use anything but will need to cache the filename
+	 * for use in the dso_bind handler. All in all, let each
+	 * method control its own destiny. "Handles" and such go in
+	 * a STACK. */
+	STACK *meth_data;
+	int references;
+	int flags;
+	/* For use by applications etc ... use this for your bits'n'pieces,
+	 * don't touch meth_data! */
+	CRYPTO_EX_DATA ex_data;
+	/* If this callback function pointer is set to non-NULL, then it will
+	 * be used in DSO_load() in place of meth->dso_name_converter. NB: This
+	 * should normally set using DSO_set_name_converter(). */
+	DSO_NAME_CONVERTER_FUNC name_converter;
+	/* If this callback function pointer is set to non-NULL, then it will
+	 * be used in DSO_load() in place of meth->dso_merger. NB: This
+	 * should normally set using DSO_set_merger(). */
+	DSO_MERGER_FUNC merger;
+	/* This is populated with (a copy of) the platform-independant
+	 * filename used for this DSO. */
+	char *filename;
+	/* This is populated with (a copy of) the translated filename by which
+	 * the DSO was actually loaded. It is NULL iff the DSO is not currently
+	 * loaded. NB: This is here because the filename translation process
+	 * may involve a callback being invoked more than once not only to
+	 * convert to a platform-specific form, but also to try different
+	 * filenames in the process of trying to perform a load. As such, this
+	 * variable can be used to indicate (a) whether this DSO structure
+	 * corresponds to a loaded library or not, and (b) the filename with
+	 * which it was actually loaded. */
+	char *loaded_filename;
+	};
+
+
+DSO *	DSO_new(void);
+DSO *	DSO_new_method(DSO_METHOD *method);
+int	DSO_free(DSO *dso);
+int	DSO_flags(DSO *dso);
+int	DSO_up_ref(DSO *dso);
+long	DSO_ctrl(DSO *dso, int cmd, long larg, void *parg);
+
+/* This function sets the DSO's name_converter callback. If it is non-NULL,
+ * then it will be used instead of the associated DSO_METHOD's function. If
+ * oldcb is non-NULL then it is set to the function pointer value being
+ * replaced. Return value is non-zero for success. */
+int	DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb,
+				DSO_NAME_CONVERTER_FUNC *oldcb);
+/* These functions can be used to get/set the platform-independant filename
+ * used for a DSO. NB: set will fail if the DSO is already loaded. */
+const char *DSO_get_filename(DSO *dso);
+int	DSO_set_filename(DSO *dso, const char *filename);
+/* This function will invoke the DSO's name_converter callback to translate a
+ * filename, or if the callback isn't set it will instead use the DSO_METHOD's
+ * converter. If "filename" is NULL, the "filename" in the DSO itself will be
+ * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is
+ * simply duplicated. NB: This function is usually called from within a
+ * DSO_METHOD during the processing of a DSO_load() call, and is exposed so that
+ * caller-created DSO_METHODs can do the same thing. A non-NULL return value
+ * will need to be OPENSSL_free()'d. */
+char	*DSO_convert_filename(DSO *dso, const char *filename);
+/* This function will invoke the DSO's merger callback to merge two file
+ * specifications, or if the callback isn't set it will instead use the
+ * DSO_METHOD's merger.  A non-NULL return value will need to be
+ * OPENSSL_free()'d. */
+char	*DSO_merge(DSO *dso, const char *filespec1, const char *filespec2);
+/* If the DSO is currently loaded, this returns the filename that it was loaded
+ * under, otherwise it returns NULL. So it is also useful as a test as to
+ * whether the DSO is currently loaded. NB: This will not necessarily return
+ * the same value as DSO_convert_filename(dso, dso->filename), because the
+ * DSO_METHOD's load function may have tried a variety of filenames (with
+ * and/or without the aid of the converters) before settling on the one it
+ * actually loaded. */
+const char *DSO_get_loaded_filename(DSO *dso);
+
+void	DSO_set_default_method(DSO_METHOD *meth);
+DSO_METHOD *DSO_get_default_method(void);
+DSO_METHOD *DSO_get_method(DSO *dso);
+DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth);
+
+/* The all-singing all-dancing load function, you normally pass NULL
+ * for the first and third parameters. Use DSO_up and DSO_free for
+ * subsequent reference count handling. Any flags passed in will be set
+ * in the constructed DSO after its init() function but before the
+ * load operation. If 'dso' is non-NULL, 'flags' is ignored. */
+DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags);
+
+/* This function binds to a variable inside a shared library. */
+void *DSO_bind_var(DSO *dso, const char *symname);
+
+/* This function binds to a function inside a shared library. */
+DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname);
+
+/* This method is the default, but will beg, borrow, or steal whatever
+ * method should be the default on any particular platform (including
+ * DSO_METH_null() if necessary). */
+DSO_METHOD *DSO_METHOD_openssl(void);
+
+/* This method is defined for all platforms - if a platform has no
+ * DSO support then this will be the only method! */
+DSO_METHOD *DSO_METHOD_null(void);
+
+/* If DSO_DLFCN is defined, the standard dlfcn.h-style functions
+ * (dlopen, dlclose, dlsym, etc) will be used and incorporated into
+ * this method. If not, this method will return NULL. */
+DSO_METHOD *DSO_METHOD_dlfcn(void);
+
+/* If DSO_DL is defined, the standard dl.h-style functions (shl_load, 
+ * shl_unload, shl_findsym, etc) will be used and incorporated into
+ * this method. If not, this method will return NULL. */
+DSO_METHOD *DSO_METHOD_dl(void);
+
+/* If WIN32 is defined, use DLLs. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_win32(void);
+
+/* If VMS is defined, use shared images. If not, return NULL. */
+DSO_METHOD *DSO_METHOD_vms(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_DSO_strings(void);
+
+/* Error codes for the DSO functions. */
+
+/* Function codes. */
+#define DSO_F_DLFCN_BIND_FUNC				 100
+#define DSO_F_DLFCN_BIND_VAR				 101
+#define DSO_F_DLFCN_LOAD				 102
+#define DSO_F_DLFCN_MERGER				 130
+#define DSO_F_DLFCN_NAME_CONVERTER			 123
+#define DSO_F_DLFCN_UNLOAD				 103
+#define DSO_F_DL_BIND_FUNC				 104
+#define DSO_F_DL_BIND_VAR				 105
+#define DSO_F_DL_LOAD					 106
+#define DSO_F_DL_MERGER					 131
+#define DSO_F_DL_NAME_CONVERTER				 124
+#define DSO_F_DL_UNLOAD					 107
+#define DSO_F_DSO_BIND_FUNC				 108
+#define DSO_F_DSO_BIND_VAR				 109
+#define DSO_F_DSO_CONVERT_FILENAME			 126
+#define DSO_F_DSO_CTRL					 110
+#define DSO_F_DSO_FREE					 111
+#define DSO_F_DSO_GET_FILENAME				 127
+#define DSO_F_DSO_GET_LOADED_FILENAME			 128
+#define DSO_F_DSO_LOAD					 112
+#define DSO_F_DSO_MERGE					 132
+#define DSO_F_DSO_NEW_METHOD				 113
+#define DSO_F_DSO_SET_FILENAME				 129
+#define DSO_F_DSO_SET_NAME_CONVERTER			 122
+#define DSO_F_DSO_UP_REF				 114
+#define DSO_F_VMS_BIND_SYM				 115
+#define DSO_F_VMS_LOAD					 116
+#define DSO_F_VMS_MERGER				 133
+#define DSO_F_VMS_UNLOAD				 117
+#define DSO_F_WIN32_BIND_FUNC				 118
+#define DSO_F_WIN32_BIND_VAR				 119
+#define DSO_F_WIN32_JOINER				 135
+#define DSO_F_WIN32_LOAD				 120
+#define DSO_F_WIN32_MERGER				 134
+#define DSO_F_WIN32_NAME_CONVERTER			 125
+#define DSO_F_WIN32_SPLITTER				 136
+#define DSO_F_WIN32_UNLOAD				 121
+
+/* Reason codes. */
+#define DSO_R_CTRL_FAILED				 100
+#define DSO_R_DSO_ALREADY_LOADED			 110
+#define DSO_R_EMPTY_FILE_STRUCTURE			 113
+#define DSO_R_FAILURE					 114
+#define DSO_R_FILENAME_TOO_BIG				 101
+#define DSO_R_FINISH_FAILED				 102
+#define DSO_R_INCORRECT_FILE_SYNTAX			 115
+#define DSO_R_LOAD_FAILED				 103
+#define DSO_R_NAME_TRANSLATION_FAILED			 109
+#define DSO_R_NO_FILENAME				 111
+#define DSO_R_NO_FILE_SPECIFICATION			 116
+#define DSO_R_NULL_HANDLE				 104
+#define DSO_R_SET_FILENAME_FAILED			 112
+#define DSO_R_STACK_ERROR				 105
+#define DSO_R_SYM_FAILURE				 106
+#define DSO_R_UNLOAD_FAILED				 107
+#define DSO_R_UNSUPPORTED				 108
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dtls1.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dtls1.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/dtls1.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,212 @@
+/* ssl/dtls1.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_DTLS1_H 
+#define HEADER_DTLS1_H 
+
+#include <openssl/buffer.h>
+#include <openssl/pqueue.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define DTLS1_VERSION			0x0100
+#define DTLS1_VERSION_MAJOR		0x01
+#define DTLS1_VERSION_MINOR		0x00
+
+#define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE    110
+
+/* lengths of messages */
+#define DTLS1_COOKIE_LENGTH                     32
+
+#define DTLS1_RT_HEADER_LENGTH                  13
+
+#define DTLS1_HM_HEADER_LENGTH                  12
+
+#define DTLS1_HM_BAD_FRAGMENT                   -2
+#define DTLS1_HM_FRAGMENT_RETRY                 -3
+
+#define DTLS1_CCS_HEADER_LENGTH                  3
+
+#define DTLS1_AL_HEADER_LENGTH                   7
+
+
+typedef struct dtls1_bitmap_st
+	{
+	PQ_64BIT map;
+	unsigned long length;     /* sizeof the bitmap in bits */
+	PQ_64BIT max_seq_num;  /* max record number seen so far */
+	} DTLS1_BITMAP;
+
+struct hm_header_st
+	{
+	unsigned char type;
+	unsigned long msg_len;
+	unsigned short seq;
+	unsigned long frag_off;
+	unsigned long frag_len;
+	unsigned int is_ccs;
+	};
+
+struct ccs_header_st
+	{
+	unsigned char type;
+	unsigned short seq;
+	};
+
+struct dtls1_timeout_st
+	{
+	/* Number of read timeouts so far */
+	unsigned int read_timeouts;
+	
+	/* Number of write timeouts so far */
+	unsigned int write_timeouts;
+	
+	/* Number of alerts received so far */
+	unsigned int num_alerts;
+	};
+
+typedef struct record_pqueue_st
+	{
+	unsigned short epoch;
+	pqueue q;
+	} record_pqueue;
+
+typedef struct hm_fragment_st
+	{
+	struct hm_header_st msg_header;
+	unsigned char *fragment;
+	} hm_fragment;
+
+typedef struct dtls1_state_st
+	{
+	unsigned int send_cookie;
+	unsigned char cookie[DTLS1_COOKIE_LENGTH];
+	unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH];
+	unsigned int cookie_len;
+
+	/* 
+	 * The current data and handshake epoch.  This is initially
+	 * undefined, and starts at zero once the initial handshake is
+	 * completed 
+	 */
+	unsigned short r_epoch;
+	unsigned short w_epoch;
+
+	/* records being received in the current epoch */
+	DTLS1_BITMAP bitmap;
+
+	/* renegotiation starts a new set of sequence numbers */
+	DTLS1_BITMAP next_bitmap;
+
+	/* handshake message numbers */
+	unsigned short handshake_write_seq;
+	unsigned short next_handshake_write_seq;
+
+	unsigned short handshake_read_seq;
+
+	/* Received handshake records (processed and unprocessed) */
+	record_pqueue unprocessed_rcds;
+	record_pqueue processed_rcds;
+
+	/* Buffered handshake messages */
+	pqueue buffered_messages;
+
+	/* Buffered (sent) handshake records */
+	pqueue sent_messages;
+
+	unsigned int mtu; /* max wire packet size */
+
+	struct hm_header_st w_msg_hdr;
+	struct hm_header_st r_msg_hdr;
+
+	struct dtls1_timeout_st timeout;
+	
+	/* storage for Alert/Handshake protocol data received but not
+	 * yet processed by ssl3_read_bytes: */
+	unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
+	unsigned int alert_fragment_len;
+	unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH];
+	unsigned int handshake_fragment_len;
+
+	unsigned int retransmitting;
+
+	} DTLS1_STATE;
+
+typedef struct dtls1_record_data_st
+	{
+	unsigned char *packet;
+	unsigned int   packet_length;
+	SSL3_BUFFER    rbuf;
+	SSL3_RECORD    rrec;
+	} DTLS1_RECORD_DATA;
+
+
+/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
+#define DTLS1_TMO_READ_COUNT                      2
+#define DTLS1_TMO_WRITE_COUNT                     2
+
+#define DTLS1_TMO_ALERT_COUNT                     12
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/e_os2.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/e_os2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/e_os2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,285 @@
+/* e_os2.h */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/opensslconf.h>
+
+#ifndef HEADER_E_OS2_H
+#define HEADER_E_OS2_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************
+ * Detect operating systems.  This probably needs completing.
+ * The result is that at least one OPENSSL_SYS_os macro should be defined.
+ * However, if none is defined, Unix is assumed.
+ **/
+
+#define OPENSSL_SYS_UNIX
+
+/* ----------------------- Macintosh, before MacOS X ----------------------- */
+#if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_MACINTOSH_CLASSIC
+#endif
+
+/* ----------------------- NetWare ----------------------------------------- */
+#if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_NETWARE
+#endif
+
+/* ---------------------- Microsoft operating systems ---------------------- */
+
+/* The 16 bit environments are pretty straightforward */
+#if defined(OPENSSL_SYSNAME_WIN16) || defined(OPENSSL_SYSNAME_MSDOS)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_MSDOS
+#endif
+#if defined(OPENSSL_SYSNAME_WIN16)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WIN16
+#endif
+
+/* For 32 bit environment, there seems to be the CygWin environment and then
+   all the others that try to do the same thing Microsoft does... */
+#if defined(OPENSSL_SYSNAME_UWIN)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WIN32_UWIN
+#else
+# if defined(__CYGWIN32__) || defined(OPENSSL_SYSNAME_CYGWIN32)
+#  undef OPENSSL_SYS_UNIX
+#  define OPENSSL_SYS_WIN32_CYGWIN
+# else
+#  if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WIN32
+#  endif
+#  if defined(OPENSSL_SYSNAME_WINNT)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WINNT
+#  endif
+#  if defined(OPENSSL_SYSNAME_WINCE)
+#   undef OPENSSL_SYS_UNIX
+#   define OPENSSL_SYS_WINCE
+#  endif
+# endif
+#endif
+
+/* Anything that tries to look like Microsoft is "Windows" */
+#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_WINDOWS
+# ifndef OPENSSL_SYS_MSDOS
+#  define OPENSSL_SYS_MSDOS
+# endif
+#endif
+
+/* DLL settings.  This part is a bit tough, because it's up to the application
+   implementor how he or she will link the application, so it requires some
+   macro to be used. */
+#ifdef OPENSSL_SYS_WINDOWS
+# ifndef OPENSSL_OPT_WINDLL
+#  if defined(_WINDLL) /* This is used when building OpenSSL to indicate that
+                          DLL linkage should be used */
+#   define OPENSSL_OPT_WINDLL
+#  endif
+# endif
+#endif
+
+/* -------------------------------- OpenVMS -------------------------------- */
+#if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_VMS
+# if defined(__DECC)
+#  define OPENSSL_SYS_VMS_DECC
+# elif defined(__DECCXX)
+#  define OPENSSL_SYS_VMS_DECC
+#  define OPENSSL_SYS_VMS_DECCXX
+# else
+#  define OPENSSL_SYS_VMS_NODECC
+# endif
+#endif
+
+/* --------------------------------- OS/2 ---------------------------------- */
+#if defined(__EMX__) || defined(__OS2__)
+# undef OPENSSL_SYS_UNIX
+# define OPENSSL_SYS_OS2
+#endif
+
+/* --------------------------------- Unix ---------------------------------- */
+#ifdef OPENSSL_SYS_UNIX
+# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX)
+#  define OPENSSL_SYS_LINUX
+# endif
+# ifdef OPENSSL_SYSNAME_MPE
+#  define OPENSSL_SYS_MPE
+# endif
+# ifdef OPENSSL_SYSNAME_SNI
+#  define OPENSSL_SYS_SNI
+# endif
+# ifdef OPENSSL_SYSNAME_ULTRASPARC
+#  define OPENSSL_SYS_ULTRASPARC
+# endif
+# ifdef OPENSSL_SYSNAME_NEWS4
+#  define OPENSSL_SYS_NEWS4
+# endif
+# ifdef OPENSSL_SYSNAME_MACOSX
+#  define OPENSSL_SYS_MACOSX
+# endif
+# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY
+#  define OPENSSL_SYS_MACOSX_RHAPSODY
+#  define OPENSSL_SYS_MACOSX
+# endif
+# ifdef OPENSSL_SYSNAME_SUNOS
+#  define OPENSSL_SYS_SUNOS
+#endif
+# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY)
+#  define OPENSSL_SYS_CRAY
+# endif
+# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX)
+#  define OPENSSL_SYS_AIX
+# endif
+#endif
+
+/* --------------------------------- VOS ----------------------------------- */
+#ifdef OPENSSL_SYSNAME_VOS
+# define OPENSSL_SYS_VOS
+#endif
+
+/* ------------------------------- VxWorks --------------------------------- */
+#ifdef OPENSSL_SYSNAME_VXWORKS
+# define OPENSSL_SYS_VXWORKS
+#endif
+
+/**
+ * That's it for OS-specific stuff
+ *****************************************************************************/
+
+
+/* Specials for I/O an exit */
+#ifdef OPENSSL_SYS_WIN16
+# define OPENSSL_NO_FP_API
+#endif
+#ifdef OPENSSL_SYS_MSDOS
+# define OPENSSL_UNISTD_IO <io.h>
+# define OPENSSL_DECLARE_EXIT extern void exit(int);
+#else
+# define OPENSSL_UNISTD_IO OPENSSL_UNISTD
+# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */
+#endif
+
+/* Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare
+   certain global symbols that, with some compilers under VMS, have to be
+   defined and declared explicitely with globaldef and globalref.
+   Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare
+   DLL exports and imports for compilers under Win32.  These are a little
+   more complicated to use.  Basically, for any library that exports some
+   global variables, the following code must be present in the header file
+   that declares them, before OPENSSL_EXTERN is used:
+
+   #ifdef SOME_BUILD_FLAG_MACRO
+   # undef OPENSSL_EXTERN
+   # define OPENSSL_EXTERN OPENSSL_EXPORT
+   #endif
+
+   The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL
+   have some generally sensible values, and for OPENSSL_EXTERN to have the
+   value OPENSSL_IMPORT.
+*/
+
+#if defined(OPENSSL_SYS_VMS_NODECC)
+# define OPENSSL_EXPORT globalref
+# define OPENSSL_IMPORT globalref
+# define OPENSSL_GLOBAL globaldef
+#elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL)
+# define OPENSSL_EXPORT extern __declspec(dllexport)
+# define OPENSSL_IMPORT extern __declspec(dllimport)
+# define OPENSSL_GLOBAL
+#else
+# define OPENSSL_EXPORT extern
+# define OPENSSL_IMPORT extern
+# define OPENSSL_GLOBAL
+#endif
+#define OPENSSL_EXTERN OPENSSL_IMPORT
+
+/* Macros to allow global variables to be reached through function calls when
+   required (if a shared library version requvres it, for example.
+   The way it's done allows definitions like this:
+
+	// in foobar.c
+	OPENSSL_IMPLEMENT_GLOBAL(int,foobar) = 0;
+	// in foobar.h
+	OPENSSL_DECLARE_GLOBAL(int,foobar);
+	#define foobar OPENSSL_GLOBAL_REF(foobar)
+*/
+#ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name)			     \
+	extern type _hide_##name;				     \
+	type *_shadow_##name(void) { return &_hide_##name; }	     \
+	static type _hide_##name
+# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void)
+# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name()))
+#else
+# define OPENSSL_IMPLEMENT_GLOBAL(type,name) OPENSSL_GLOBAL type _shadow_##name
+# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name
+# define OPENSSL_GLOBAL_REF(name) _shadow_##name
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ebcdic.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ebcdic.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ebcdic.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,19 @@
+/* crypto/ebcdic.h */
+
+#ifndef HEADER_EBCDIC_H
+#define HEADER_EBCDIC_H
+
+#include <sys/types.h>
+
+/* Avoid name clashes with other applications */
+#define os_toascii   _openssl_os_toascii
+#define os_toebcdic  _openssl_os_toebcdic
+#define ebcdic2ascii _openssl_ebcdic2ascii
+#define ascii2ebcdic _openssl_ascii2ebcdic
+
+extern const unsigned char os_toascii[256];
+extern const unsigned char os_toebcdic[256];
+void *ebcdic2ascii(void *dest, const void *srce, size_t count);
+void *ascii2ebcdic(void *dest, const void *srce, size_t count);
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ec.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ec.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ec.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,518 @@
+/* crypto/ec/ec.h */
+/*
+ * Originally written by Bodo Moeller for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * The elliptic curve binary polynomial software is originally written by 
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_EC_H
+#define HEADER_EC_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_EC
+#error EC is disabled.
+#endif
+
+#include <openssl/asn1.h>
+#include <openssl/symhacks.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#elif defined(__SUNPRO_C)
+# if __SUNPRO_C >= 0x520
+# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+# endif
+#endif
+
+
+typedef enum {
+	/* values as defined in X9.62 (ECDSA) and elsewhere */
+	POINT_CONVERSION_COMPRESSED = 2,
+	POINT_CONVERSION_UNCOMPRESSED = 4,
+	POINT_CONVERSION_HYBRID = 6
+} point_conversion_form_t;
+
+
+typedef struct ec_method_st EC_METHOD;
+
+typedef struct ec_group_st
+	/*
+	 EC_METHOD *meth;
+	 -- field definition
+	 -- curve coefficients
+	 -- optional generator with associated information (order, cofactor)
+	 -- optional extra data (precomputed table for fast computation of multiples of generator)
+	 -- ASN1 stuff
+	*/
+	EC_GROUP;
+
+typedef struct ec_point_st EC_POINT;
+
+
+/* EC_METHODs for curves over GF(p).
+ * EC_GFp_simple_method provides the basis for the optimized methods.
+ */
+const EC_METHOD *EC_GFp_simple_method(void);
+const EC_METHOD *EC_GFp_mont_method(void);
+const EC_METHOD *EC_GFp_nist_method(void);
+
+/* EC_METHOD for curves over GF(2^m).
+ */
+const EC_METHOD *EC_GF2m_simple_method(void);
+
+
+EC_GROUP *EC_GROUP_new(const EC_METHOD *);
+void EC_GROUP_free(EC_GROUP *);
+void EC_GROUP_clear_free(EC_GROUP *);
+int EC_GROUP_copy(EC_GROUP *, const EC_GROUP *);
+EC_GROUP *EC_GROUP_dup(const EC_GROUP *);
+
+const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *);
+int EC_METHOD_get_field_type(const EC_METHOD *);
+
+int EC_GROUP_set_generator(EC_GROUP *, const EC_POINT *generator, const BIGNUM *order, const BIGNUM *cofactor);
+const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
+int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
+int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
+
+void EC_GROUP_set_curve_name(EC_GROUP *, int nid);
+int EC_GROUP_get_curve_name(const EC_GROUP *);
+
+void EC_GROUP_set_asn1_flag(EC_GROUP *, int flag);
+int EC_GROUP_get_asn1_flag(const EC_GROUP *);
+
+void EC_GROUP_set_point_conversion_form(EC_GROUP *, point_conversion_form_t);
+point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *);
+
+unsigned char *EC_GROUP_get0_seed(const EC_GROUP *);
+size_t EC_GROUP_get_seed_len(const EC_GROUP *);
+size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len);
+
+int EC_GROUP_set_curve_GFp(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int EC_GROUP_get_curve_GFp(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+int EC_GROUP_set_curve_GF2m(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+int EC_GROUP_get_curve_GF2m(const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, BN_CTX *);
+
+/* returns the number of bits needed to represent a field element */
+int EC_GROUP_get_degree(const EC_GROUP *);
+
+/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
+/* EC_GROUP_check_discriminant() returns 1 if the discriminant of the
+ * elliptic curve is not zero, 0 otherwise */
+int EC_GROUP_check_discriminant(const EC_GROUP *, BN_CTX *);
+
+/* EC_GROUP_cmp() returns 0 if both groups are equal and 1 otherwise */
+int EC_GROUP_cmp(const EC_GROUP *, const EC_GROUP *, BN_CTX *);
+
+/* EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*()
+ * after choosing an appropriate EC_METHOD */
+EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, const BIGNUM *b, BN_CTX *);
+
+/* EC_GROUP_new_by_curve_name() creates a EC_GROUP structure
+ * specified by a curve name (in form of a NID) */
+EC_GROUP *EC_GROUP_new_by_curve_name(int nid);
+/* handling of internal curves */
+typedef struct { 
+	int nid;
+	const char *comment;
+	} EC_builtin_curve;
+/* EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number 
+ * of all available curves or zero if a error occurred. 
+ * In case r ist not zero nitems EC_builtin_curve structures 
+ * are filled with the data of the first nitems internal groups */
+size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems);
+
+
+/* EC_POINT functions */
+
+EC_POINT *EC_POINT_new(const EC_GROUP *);
+void EC_POINT_free(EC_POINT *);
+void EC_POINT_clear_free(EC_POINT *);
+int EC_POINT_copy(EC_POINT *, const EC_POINT *);
+EC_POINT *EC_POINT_dup(const EC_POINT *, const EC_GROUP *);
+ 
+const EC_METHOD *EC_POINT_method_of(const EC_POINT *);
+
+int EC_POINT_set_to_infinity(const EC_GROUP *, EC_POINT *);
+int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, const BIGNUM *z, BN_CTX *);
+int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BIGNUM *z, BN_CTX *);
+int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BN_CTX *);
+int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, int y_bit, BN_CTX *);
+
+int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, const BIGNUM *y, BN_CTX *);
+int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *, const EC_POINT *,
+	BIGNUM *x, BIGNUM *y, BN_CTX *);
+int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *, EC_POINT *,
+	const BIGNUM *x, int y_bit, BN_CTX *);
+
+size_t EC_POINT_point2oct(const EC_GROUP *, const EC_POINT *, point_conversion_form_t form,
+        unsigned char *buf, size_t len, BN_CTX *);
+int EC_POINT_oct2point(const EC_GROUP *, EC_POINT *,
+        const unsigned char *buf, size_t len, BN_CTX *);
+
+/* other interfaces to point2oct/oct2point: */
+BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *,
+	point_conversion_form_t form, BIGNUM *, BN_CTX *);
+EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *,
+	EC_POINT *, BN_CTX *);
+char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *,
+	point_conversion_form_t form, BN_CTX *);
+EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *,
+	EC_POINT *, BN_CTX *);
+
+int EC_POINT_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+int EC_POINT_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *);
+int EC_POINT_invert(const EC_GROUP *, EC_POINT *, BN_CTX *);
+
+int EC_POINT_is_at_infinity(const EC_GROUP *, const EC_POINT *);
+int EC_POINT_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *);
+int EC_POINT_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, BN_CTX *);
+
+int EC_POINT_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *);
+int EC_POINTs_make_affine(const EC_GROUP *, size_t num, EC_POINT *[], BN_CTX *);
+
+
+int EC_POINTs_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, size_t num, const EC_POINT *[], const BIGNUM *[], BN_CTX *);
+int EC_POINT_mul(const EC_GROUP *, EC_POINT *r, const BIGNUM *, const EC_POINT *, const BIGNUM *, BN_CTX *);
+
+/* EC_GROUP_precompute_mult() stores multiples of generator for faster point multiplication */
+int EC_GROUP_precompute_mult(EC_GROUP *, BN_CTX *);
+/* EC_GROUP_have_precompute_mult() reports whether such precomputation has been done */
+int EC_GROUP_have_precompute_mult(const EC_GROUP *);
+
+
+
+/* ASN1 stuff */
+
+/* EC_GROUP_get_basis_type() returns the NID of the basis type
+ * used to represent the field elements */
+int EC_GROUP_get_basis_type(const EC_GROUP *);
+int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k);
+int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, 
+	unsigned int *k2, unsigned int *k3);
+
+#define OPENSSL_EC_NAMED_CURVE	0x001
+
+typedef struct ecpk_parameters_st ECPKPARAMETERS;
+
+EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len);
+int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out);
+
+#define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x)
+#define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x)
+#define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \
+                (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x))
+#define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \
+		(unsigned char *)(x))
+
+#ifndef OPENSSL_NO_BIO
+int     ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off);
+#endif
+#ifndef OPENSSL_NO_FP_API
+int     ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off);
+#endif
+
+/* the EC_KEY stuff */
+typedef struct ec_key_st EC_KEY;
+
+/* some values for the encoding_flag */
+#define EC_PKEY_NO_PARAMETERS	0x001
+#define EC_PKEY_NO_PUBKEY	0x002
+
+EC_KEY *EC_KEY_new(void);
+EC_KEY *EC_KEY_new_by_curve_name(int nid);
+void EC_KEY_free(EC_KEY *);
+EC_KEY *EC_KEY_copy(EC_KEY *, const EC_KEY *);
+EC_KEY *EC_KEY_dup(const EC_KEY *);
+
+int EC_KEY_up_ref(EC_KEY *);
+
+const EC_GROUP *EC_KEY_get0_group(const EC_KEY *);
+int EC_KEY_set_group(EC_KEY *, const EC_GROUP *);
+const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *);
+int EC_KEY_set_private_key(EC_KEY *, const BIGNUM *);
+const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *);
+int EC_KEY_set_public_key(EC_KEY *, const EC_POINT *);
+unsigned EC_KEY_get_enc_flags(const EC_KEY *);
+void EC_KEY_set_enc_flags(EC_KEY *, unsigned int);
+point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *);
+void EC_KEY_set_conv_form(EC_KEY *, point_conversion_form_t);
+/* functions to set/get method specific data  */
+void *EC_KEY_get_key_method_data(EC_KEY *, 
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+void EC_KEY_insert_key_method_data(EC_KEY *, void *data,
+	void *(*dup_func)(void *), void (*free_func)(void *), void (*clear_free_func)(void *));
+/* wrapper functions for the underlying EC_GROUP object */
+void EC_KEY_set_asn1_flag(EC_KEY *, int);
+int EC_KEY_precompute_mult(EC_KEY *, BN_CTX *ctx);
+
+/* EC_KEY_generate_key() creates a ec private (public) key */
+int EC_KEY_generate_key(EC_KEY *);
+/* EC_KEY_check_key() */
+int EC_KEY_check_key(const EC_KEY *);
+
+/* de- and encoding functions for SEC1 ECPrivateKey */
+EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len);
+int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out);
+/* de- and encoding functions for EC parameters */
+EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len);
+int i2d_ECParameters(EC_KEY *a, unsigned char **out);
+/* de- and encoding functions for EC public key
+ * (octet string, not DER -- hence 'o2i' and 'i2o') */
+EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len);
+int i2o_ECPublicKey(EC_KEY *a, unsigned char **out);
+
+#ifndef OPENSSL_NO_BIO
+int	ECParameters_print(BIO *bp, const EC_KEY *x);
+int	EC_KEY_print(BIO *bp, const EC_KEY *x, int off);
+#endif
+#ifndef OPENSSL_NO_FP_API
+int	ECParameters_print_fp(FILE *fp, const EC_KEY *x);
+int	EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off);
+#endif
+
+#define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x)
+
+#ifndef __cplusplus
+#if defined(__SUNPRO_C)
+#  if __SUNPRO_C >= 0x520
+# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE)
+#  endif
+# endif
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_EC_strings(void);
+
+/* Error codes for the EC functions. */
+
+/* Function codes. */
+#define EC_F_COMPUTE_WNAF				 143
+#define EC_F_D2I_ECPARAMETERS				 144
+#define EC_F_D2I_ECPKPARAMETERS				 145
+#define EC_F_D2I_ECPRIVATEKEY				 146
+#define EC_F_ECPARAMETERS_PRINT				 147
+#define EC_F_ECPARAMETERS_PRINT_FP			 148
+#define EC_F_ECPKPARAMETERS_PRINT			 149
+#define EC_F_ECPKPARAMETERS_PRINT_FP			 150
+#define EC_F_ECP_NIST_MOD_192				 203
+#define EC_F_ECP_NIST_MOD_224				 204
+#define EC_F_ECP_NIST_MOD_256				 205
+#define EC_F_ECP_NIST_MOD_521				 206
+#define EC_F_EC_ASN1_GROUP2CURVE			 153
+#define EC_F_EC_ASN1_GROUP2FIELDID			 154
+#define EC_F_EC_ASN1_GROUP2PARAMETERS			 155
+#define EC_F_EC_ASN1_GROUP2PKPARAMETERS			 156
+#define EC_F_EC_ASN1_PARAMETERS2GROUP			 157
+#define EC_F_EC_ASN1_PKPARAMETERS2GROUP			 158
+#define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY		 208
+#define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT	 159
+#define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE		 195
+#define EC_F_EC_GF2M_SIMPLE_OCT2POINT			 160
+#define EC_F_EC_GF2M_SIMPLE_POINT2OCT			 161
+#define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162
+#define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163
+#define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES	 164
+#define EC_F_EC_GFP_MONT_FIELD_DECODE			 133
+#define EC_F_EC_GFP_MONT_FIELD_ENCODE			 134
+#define EC_F_EC_GFP_MONT_FIELD_MUL			 131
+#define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE		 209
+#define EC_F_EC_GFP_MONT_FIELD_SQR			 132
+#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE		 189
+#define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP		 135
+#define EC_F_EC_GFP_NIST_FIELD_MUL			 200
+#define EC_F_EC_GFP_NIST_FIELD_SQR			 201
+#define EC_F_EC_GFP_NIST_GROUP_SET_CURVE		 202
+#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT	 165
+#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE		 166
+#define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP		 100
+#define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR		 101
+#define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE			 102
+#define EC_F_EC_GFP_SIMPLE_OCT2POINT			 103
+#define EC_F_EC_GFP_SIMPLE_POINT2OCT			 104
+#define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE		 137
+#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES	 167
+#define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
+#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES	 168
+#define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
+#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES	 169
+#define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
+#define EC_F_EC_GROUP_CHECK				 170
+#define EC_F_EC_GROUP_CHECK_DISCRIMINANT		 171
+#define EC_F_EC_GROUP_COPY				 106
+#define EC_F_EC_GROUP_GET0_GENERATOR			 139
+#define EC_F_EC_GROUP_GET_COFACTOR			 140
+#define EC_F_EC_GROUP_GET_CURVE_GF2M			 172
+#define EC_F_EC_GROUP_GET_CURVE_GFP			 130
+#define EC_F_EC_GROUP_GET_DEGREE			 173
+#define EC_F_EC_GROUP_GET_ORDER				 141
+#define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS		 193
+#define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS		 194
+#define EC_F_EC_GROUP_GROUP2NID				 147
+#define EC_F_EC_GROUP_NEW				 108
+#define EC_F_EC_GROUP_NEW_BY_CURVE_NAME			 174
+#define EC_F_EC_GROUP_NEW_FROM_DATA			 175
+#define EC_F_EC_GROUP_PRECOMPUTE_MULT			 142
+#define EC_F_EC_GROUP_SET_CURVE_GF2M			 176
+#define EC_F_EC_GROUP_SET_CURVE_GFP			 109
+#define EC_F_EC_GROUP_SET_EXTRA_DATA			 110
+#define EC_F_EC_GROUP_SET_GENERATOR			 111
+#define EC_F_EC_KEY_CHECK_KEY				 177
+#define EC_F_EC_KEY_COPY				 178
+#define EC_F_EC_KEY_GENERATE_KEY			 179
+#define EC_F_EC_KEY_NEW					 182
+#define EC_F_EC_KEY_PRINT				 180
+#define EC_F_EC_KEY_PRINT_FP				 181
+#define EC_F_EC_POINTS_MAKE_AFFINE			 136
+#define EC_F_EC_POINTS_MUL				 138
+#define EC_F_EC_POINT_ADD				 112
+#define EC_F_EC_POINT_CMP				 113
+#define EC_F_EC_POINT_COPY				 114
+#define EC_F_EC_POINT_DBL				 115
+#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M	 183
+#define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP	 116
+#define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP	 117
+#define EC_F_EC_POINT_INVERT				 210
+#define EC_F_EC_POINT_IS_AT_INFINITY			 118
+#define EC_F_EC_POINT_IS_ON_CURVE			 119
+#define EC_F_EC_POINT_MAKE_AFFINE			 120
+#define EC_F_EC_POINT_MUL				 184
+#define EC_F_EC_POINT_NEW				 121
+#define EC_F_EC_POINT_OCT2POINT				 122
+#define EC_F_EC_POINT_POINT2OCT				 123
+#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M	 185
+#define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP	 124
+#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M	 186
+#define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP	 125
+#define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP	 126
+#define EC_F_EC_POINT_SET_TO_INFINITY			 127
+#define EC_F_EC_PRE_COMP_DUP				 207
+#define EC_F_EC_WNAF_MUL				 187
+#define EC_F_EC_WNAF_PRECOMPUTE_MULT			 188
+#define EC_F_I2D_ECPARAMETERS				 190
+#define EC_F_I2D_ECPKPARAMETERS				 191
+#define EC_F_I2D_ECPRIVATEKEY				 192
+#define EC_F_I2O_ECPUBLICKEY				 151
+#define EC_F_O2I_ECPUBLICKEY				 152
+
+/* Reason codes. */
+#define EC_R_ASN1_ERROR					 115
+#define EC_R_ASN1_UNKNOWN_FIELD				 116
+#define EC_R_BUFFER_TOO_SMALL				 100
+#define EC_R_D2I_ECPKPARAMETERS_FAILURE			 117
+#define EC_R_DISCRIMINANT_IS_ZERO			 118
+#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE		 119
+#define EC_R_GROUP2PKPARAMETERS_FAILURE			 120
+#define EC_R_I2D_ECPKPARAMETERS_FAILURE			 121
+#define EC_R_INCOMPATIBLE_OBJECTS			 101
+#define EC_R_INVALID_ARGUMENT				 112
+#define EC_R_INVALID_COMPRESSED_POINT			 110
+#define EC_R_INVALID_COMPRESSION_BIT			 109
+#define EC_R_INVALID_ENCODING				 102
+#define EC_R_INVALID_FIELD				 103
+#define EC_R_INVALID_FORM				 104
+#define EC_R_INVALID_GROUP_ORDER			 122
+#define EC_R_INVALID_PRIVATE_KEY			 123
+#define EC_R_MISSING_PARAMETERS				 124
+#define EC_R_MISSING_PRIVATE_KEY			 125
+#define EC_R_NOT_A_NIST_PRIME				 135
+#define EC_R_NOT_A_SUPPORTED_NIST_PRIME			 136
+#define EC_R_NOT_IMPLEMENTED				 126
+#define EC_R_NOT_INITIALIZED				 111
+#define EC_R_NO_FIELD_MOD				 133
+#define EC_R_PASSED_NULL_PARAMETER			 134
+#define EC_R_PKPARAMETERS2GROUP_FAILURE			 127
+#define EC_R_POINT_AT_INFINITY				 106
+#define EC_R_POINT_IS_NOT_ON_CURVE			 107
+#define EC_R_SLOT_FULL					 108
+#define EC_R_UNDEFINED_GENERATOR			 113
+#define EC_R_UNDEFINED_ORDER				 128
+#define EC_R_UNKNOWN_GROUP				 129
+#define EC_R_UNKNOWN_ORDER				 114
+#define EC_R_UNSUPPORTED_FIELD				 131
+#define EC_R_WRONG_ORDER				 130
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ecdh.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ecdh.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ecdh.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,123 @@
+/* crypto/ecdh/ecdh.h */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * The Elliptic Curve Public-Key Crypto Library (ECC Code) included
+ * herein is developed by SUN MICROSYSTEMS, INC., and is contributed
+ * to the OpenSSL project.
+ *
+ * The ECC Code is licensed pursuant to the OpenSSL open source
+ * license provided below.
+ *
+ * The ECDH software is originally written by Douglas Stebila of
+ * Sun Microsystems Laboratories.
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ECDH_H
+#define HEADER_ECDH_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_ECDH
+#error ECDH is disabled.
+#endif
+
+#include <openssl/ec.h>
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const ECDH_METHOD *ECDH_OpenSSL(void);
+
+void	  ECDH_set_default_method(const ECDH_METHOD *);
+const ECDH_METHOD *ECDH_get_default_method(void);
+int 	  ECDH_set_method(EC_KEY *, const ECDH_METHOD *);
+
+int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, EC_KEY *ecdh,
+                     void *(*KDF)(const void *in, size_t inlen, void *out, size_t *outlen));
+
+int 	  ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new 
+		*new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int 	  ECDH_set_ex_data(EC_KEY *d, int idx, void *arg);
+void 	  *ECDH_get_ex_data(EC_KEY *d, int idx);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ECDH_strings(void);
+
+/* Error codes for the ECDH functions. */
+
+/* Function codes. */
+#define ECDH_F_ECDH_COMPUTE_KEY				 100
+#define ECDH_F_ECDH_DATA_NEW_METHOD			 101
+
+/* Reason codes. */
+#define ECDH_R_KDF_FAILED				 102
+#define ECDH_R_NO_PRIVATE_VALUE				 100
+#define ECDH_R_POINT_ARITHMETIC_FAILURE			 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ecdsa.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ecdsa.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ecdsa.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,270 @@
+/* crypto/ecdsa/ecdsa.h */
+/**
+ * \file   crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions
+ * \author Written by Nils Larsch for the OpenSSL project
+ */
+/* ====================================================================
+ * Copyright (c) 2000-2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_ECDSA_H
+#define HEADER_ECDSA_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_ECDSA
+#error ECDSA is disabled.
+#endif
+
+#include <openssl/ec.h>
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct ECDSA_SIG_st
+	{
+	BIGNUM *r;
+	BIGNUM *s;
+	} ECDSA_SIG;
+
+/** ECDSA_SIG *ECDSA_SIG_new(void)
+ * allocates and initialize a ECDSA_SIG structure
+ * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
+ */
+ECDSA_SIG *ECDSA_SIG_new(void);
+
+/** ECDSA_SIG_free
+ * frees a ECDSA_SIG structure
+ * \param a pointer to the ECDSA_SIG structure
+ */
+void	  ECDSA_SIG_free(ECDSA_SIG *a);
+
+/** i2d_ECDSA_SIG
+ * DER encode content of ECDSA_SIG object (note: this function modifies *pp
+ * (*pp += length of the DER encoded signature)).
+ * \param a  pointer to the ECDSA_SIG object
+ * \param pp pointer to a unsigned char pointer for the output or NULL
+ * \return the length of the DER encoded ECDSA_SIG object or 0 
+ */
+int	  i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp);
+
+/** d2i_ECDSA_SIG
+ * decodes a DER encoded ECDSA signature (note: this function changes *pp
+ * (*pp += len)). 
+ * \param v pointer to ECDSA_SIG pointer (may be NULL)
+ * \param pp buffer with the DER encoded signature
+ * \param len bufferlength
+ * \return pointer to the decoded ECDSA_SIG structure (or NULL)
+ */
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len);
+
+/** ECDSA_do_sign
+ * computes the ECDSA signature of the given hash value using
+ * the supplied private key and returns the created signature.
+ * \param dgst pointer to the hash value
+ * \param dgst_len length of the hash value
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return pointer to a ECDSA_SIG structure or NULL
+ */
+ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey);
+
+/** ECDSA_do_sign_ex
+ * computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param kinv optional pointer to a pre-computed inverse k
+ * \param rp optional pointer to the pre-computed rp value (see 
+ *        ECDSA_sign_setup
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return pointer to a ECDSA_SIG structure or NULL
+ */
+ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, 
+		const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey);
+
+/** ECDSA_do_verify
+ * verifies that the supplied signature is a valid ECDSA
+ * signature of the supplied hash value using the supplied public key.
+ * \param dgst pointer to the hash value
+ * \param dgst_len length of the hash value
+ * \param sig  pointer to the ECDSA_SIG structure
+ * \param eckey pointer to the EC_KEY object containing a public EC key
+ * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error
+ */
+int	  ECDSA_do_verify(const unsigned char *dgst, int dgst_len,
+		const ECDSA_SIG *sig, EC_KEY* eckey);
+
+const ECDSA_METHOD *ECDSA_OpenSSL(void);
+
+/** ECDSA_set_default_method
+ * sets the default ECDSA method
+ * \param meth the new default ECDSA_METHOD
+ */
+void	  ECDSA_set_default_method(const ECDSA_METHOD *meth);
+
+/** ECDSA_get_default_method
+ * returns the default ECDSA method
+ * \return pointer to ECDSA_METHOD structure containing the default method
+ */
+const ECDSA_METHOD *ECDSA_get_default_method(void);
+
+/** ECDSA_set_method
+ * sets method to be used for the ECDSA operations
+ * \param eckey pointer to the EC_KEY object
+ * \param meth  pointer to the new method
+ * \return 1 on success and 0 otherwise 
+ */
+int 	  ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth);
+
+/** ECDSA_size
+ * returns the maximum length of the DER encoded signature
+ * \param  eckey pointer to a EC_KEY object
+ * \return numbers of bytes required for the DER encoded signature
+ */
+int	  ECDSA_size(const EC_KEY *eckey);
+
+/** ECDSA_sign_setup
+ * precompute parts of the signing operation. 
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \param ctx  pointer to a BN_CTX object (may be NULL)
+ * \param kinv pointer to a BIGNUM pointer for the inverse of k
+ * \param rp   pointer to a BIGNUM pointer for x coordinate of k * generator
+ * \return 1 on success and 0 otherwise
+ */
+int 	  ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, 
+		BIGNUM **rp);
+
+/** ECDSA_sign
+ * computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param sig buffer to hold the DER encoded signature
+ * \param siglen pointer to the length of the returned signature
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return 1 on success and 0 otherwise
+ */
+int	  ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, 
+		unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);
+
+
+/** ECDSA_sign_ex
+ * computes ECDSA signature of a given hash value using the supplied
+ * private key (note: sig must point to ECDSA_size(eckey) bytes of memory).
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value to sign
+ * \param dgstlen length of the hash value
+ * \param sig buffer to hold the DER encoded signature
+ * \param siglen pointer to the length of the returned signature
+ * \param kinv optional pointer to a pre-computed inverse k
+ * \param rp optional pointer to the pre-computed rp value (see 
+ *        ECDSA_sign_setup
+ * \param eckey pointer to the EC_KEY object containing a private EC key
+ * \return 1 on success and 0 otherwise
+ */
+int	  ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, 
+		unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv,
+		const BIGNUM *rp, EC_KEY *eckey);
+
+/** ECDSA_verify
+ * verifies that the given signature is valid ECDSA signature
+ * of the supplied hash value using the specified public key.
+ * \param type this parameter is ignored
+ * \param dgst pointer to the hash value 
+ * \param dgstlen length of the hash value
+ * \param sig  pointer to the DER encoded signature
+ * \param siglen length of the DER encoded signature
+ * \param eckey pointer to the EC_KEY object containing a public EC key
+ * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error
+ */
+int 	  ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, 
+		const unsigned char *sig, int siglen, EC_KEY *eckey);
+
+/* the standard ex_data functions */
+int 	  ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new 
+		*new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int 	  ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg);
+void 	  *ECDSA_get_ex_data(EC_KEY *d, int idx);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ECDSA_strings(void);
+
+/* Error codes for the ECDSA functions. */
+
+/* Function codes. */
+#define ECDSA_F_ECDSA_DATA_NEW_METHOD			 100
+#define ECDSA_F_ECDSA_DO_SIGN				 101
+#define ECDSA_F_ECDSA_DO_VERIFY				 102
+#define ECDSA_F_ECDSA_SIGN_SETUP			 103
+
+/* Reason codes. */
+#define ECDSA_R_BAD_SIGNATURE				 100
+#define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 101
+#define ECDSA_R_ERR_EC_LIB				 102
+#define ECDSA_R_MISSING_PARAMETERS			 103
+#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED		 104
+#define ECDSA_R_SIGNATURE_MALLOC_FAILED			 105
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/engine.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/engine.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/engine.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,801 @@
+/* openssl/engine.h */
+/* Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_ENGINE_H
+#define HEADER_ENGINE_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_ENGINE
+#error ENGINE is disabled.
+#endif
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#ifndef OPENSSL_NO_ECDH
+#include <openssl/ecdh.h>
+#endif
+#ifndef OPENSSL_NO_ECDSA
+#include <openssl/ecdsa.h>
+#endif
+#include <openssl/rand.h>
+#include <openssl/store.h>
+#include <openssl/ui.h>
+#include <openssl/err.h>
+#endif
+
+#include <openssl/ossl_typ.h>
+#include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Fixups for missing algorithms */
+#ifdef OPENSSL_NO_RSA
+typedef void RSA_METHOD;
+#endif
+#ifdef OPENSSL_NO_DSA
+typedef void DSA_METHOD;
+#endif
+#ifdef OPENSSL_NO_DH
+typedef void DH_METHOD;
+#endif
+#ifdef OPENSSL_NO_ECDH
+typedef void ECDH_METHOD;
+#endif
+#ifdef OPENSSL_NO_ECDSA
+typedef void ECDSA_METHOD;
+#endif
+
+/* These flags are used to control combinations of algorithm (methods)
+ * by bitwise "OR"ing. */
+#define ENGINE_METHOD_RSA		(unsigned int)0x0001
+#define ENGINE_METHOD_DSA		(unsigned int)0x0002
+#define ENGINE_METHOD_DH		(unsigned int)0x0004
+#define ENGINE_METHOD_RAND		(unsigned int)0x0008
+#define ENGINE_METHOD_ECDH		(unsigned int)0x0010
+#define ENGINE_METHOD_ECDSA		(unsigned int)0x0020
+#define ENGINE_METHOD_CIPHERS		(unsigned int)0x0040
+#define ENGINE_METHOD_DIGESTS		(unsigned int)0x0080
+#define ENGINE_METHOD_STORE		(unsigned int)0x0100
+/* Obvious all-or-nothing cases. */
+#define ENGINE_METHOD_ALL		(unsigned int)0xFFFF
+#define ENGINE_METHOD_NONE		(unsigned int)0x0000
+
+/* This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used
+ * internally to control registration of ENGINE implementations, and can be set
+ * by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to
+ * initialise registered ENGINEs if they are not already initialised. */
+#define ENGINE_TABLE_FLAG_NOINIT	(unsigned int)0x0001
+
+/* ENGINE flags that can be set by ENGINE_set_flags(). */
+/* #define ENGINE_FLAGS_MALLOCED	0x0001 */ /* Not used */
+
+/* This flag is for ENGINEs that wish to handle the various 'CMD'-related
+ * control commands on their own. Without this flag, ENGINE_ctrl() handles these
+ * control commands on behalf of the ENGINE using their "cmd_defns" data. */
+#define ENGINE_FLAGS_MANUAL_CMD_CTRL	(int)0x0002
+
+/* This flag is for ENGINEs who return new duplicate structures when found via
+ * "ENGINE_by_id()". When an ENGINE must store state (eg. if ENGINE_ctrl()
+ * commands are called in sequence as part of some stateful process like
+ * key-generation setup and execution), it can set this flag - then each attempt
+ * to obtain the ENGINE will result in it being copied into a new structure.
+ * Normally, ENGINEs don't declare this flag so ENGINE_by_id() just increments
+ * the existing ENGINE's structural reference count. */
+#define ENGINE_FLAGS_BY_ID_COPY		(int)0x0004
+
+/* ENGINEs can support their own command types, and these flags are used in
+ * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input each
+ * command expects. Currently only numeric and string input is supported. If a
+ * control command supports none of the _NUMERIC, _STRING, or _NO_INPUT options,
+ * then it is regarded as an "internal" control command - and not for use in
+ * config setting situations. As such, they're not available to the
+ * ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() access. Changes to
+ * this list of 'command types' should be reflected carefully in
+ * ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). */
+
+/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */
+#define ENGINE_CMD_FLAG_NUMERIC		(unsigned int)0x0001
+/* accepts string input (cast from 'void*' to 'const char *', 4th parameter to
+ * ENGINE_ctrl) */
+#define ENGINE_CMD_FLAG_STRING		(unsigned int)0x0002
+/* Indicates that the control command takes *no* input. Ie. the control command
+ * is unparameterised. */
+#define ENGINE_CMD_FLAG_NO_INPUT	(unsigned int)0x0004
+/* Indicates that the control command is internal. This control command won't
+ * be shown in any output, and is only usable through the ENGINE_ctrl_cmd()
+ * function. */
+#define ENGINE_CMD_FLAG_INTERNAL	(unsigned int)0x0008
+
+/* NB: These 3 control commands are deprecated and should not be used. ENGINEs
+ * relying on these commands should compile conditional support for
+ * compatibility (eg. if these symbols are defined) but should also migrate the
+ * same functionality to their own ENGINE-specific control functions that can be
+ * "discovered" by calling applications. The fact these control commands
+ * wouldn't be "executable" (ie. usable by text-based config) doesn't change the
+ * fact that application code can find and use them without requiring per-ENGINE
+ * hacking. */
+
+/* These flags are used to tell the ctrl function what should be done.
+ * All command numbers are shared between all engines, even if some don't
+ * make sense to some engines.  In such a case, they do nothing but return
+ * the error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. */
+#define ENGINE_CTRL_SET_LOGSTREAM		1
+#define ENGINE_CTRL_SET_PASSWORD_CALLBACK	2
+#define ENGINE_CTRL_HUP				3 /* Close and reinitialise any
+						     handles/connections etc. */
+#define ENGINE_CTRL_SET_USER_INTERFACE          4 /* Alternative to callback */
+#define ENGINE_CTRL_SET_CALLBACK_DATA           5 /* User-specific data, used
+						     when calling the password
+						     callback and the user
+						     interface */
+#define ENGINE_CTRL_LOAD_CONFIGURATION		6 /* Load a configuration, given
+						     a string that represents a
+						     file name or so */
+#define ENGINE_CTRL_LOAD_SECTION		7 /* Load data from a given
+						     section in the already loaded
+						     configuration */
+
+/* These control commands allow an application to deal with an arbitrary engine
+ * in a dynamic way. Warn: Negative return values indicate errors FOR THESE
+ * COMMANDS because zero is used to indicate 'end-of-list'. Other commands,
+ * including ENGINE-specific command types, return zero for an error.
+ *
+ * An ENGINE can choose to implement these ctrl functions, and can internally
+ * manage things however it chooses - it does so by setting the
+ * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise the
+ * ENGINE_ctrl() code handles this on the ENGINE's behalf using the cmd_defns
+ * data (set using ENGINE_set_cmd_defns()). This means an ENGINE's ctrl()
+ * handler need only implement its own commands - the above "meta" commands will
+ * be taken care of. */
+
+/* Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", then
+ * all the remaining control commands will return failure, so it is worth
+ * checking this first if the caller is trying to "discover" the engine's
+ * capabilities and doesn't want errors generated unnecessarily. */
+#define ENGINE_CTRL_HAS_CTRL_FUNCTION		10
+/* Returns a positive command number for the first command supported by the
+ * engine. Returns zero if no ctrl commands are supported. */
+#define ENGINE_CTRL_GET_FIRST_CMD_TYPE		11
+/* The 'long' argument specifies a command implemented by the engine, and the
+ * return value is the next command supported, or zero if there are no more. */
+#define ENGINE_CTRL_GET_NEXT_CMD_TYPE		12
+/* The 'void*' argument is a command name (cast from 'const char *'), and the
+ * return value is the command that corresponds to it. */
+#define ENGINE_CTRL_GET_CMD_FROM_NAME		13
+/* The next two allow a command to be converted into its corresponding string
+ * form. In each case, the 'long' argument supplies the command. In the NAME_LEN
+ * case, the return value is the length of the command name (not counting a
+ * trailing EOL). In the NAME case, the 'void*' argument must be a string buffer
+ * large enough, and it will be populated with the name of the command (WITH a
+ * trailing EOL). */
+#define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD	14
+#define ENGINE_CTRL_GET_NAME_FROM_CMD		15
+/* The next two are similar but give a "short description" of a command. */
+#define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD	16
+#define ENGINE_CTRL_GET_DESC_FROM_CMD		17
+/* With this command, the return value is the OR'd combination of
+ * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given
+ * engine-specific ctrl command expects. */
+#define ENGINE_CTRL_GET_CMD_FLAGS		18
+
+/* ENGINE implementations should start the numbering of their own control
+ * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). */
+#define ENGINE_CMD_BASE				200
+
+/* NB: These 2 nCipher "chil" control commands are deprecated, and their
+ * functionality is now available through ENGINE-specific control commands
+ * (exposed through the above-mentioned 'CMD'-handling). Code using these 2
+ * commands should be migrated to the more general command handling before these
+ * are removed. */
+
+/* Flags specific to the nCipher "chil" engine */
+#define ENGINE_CTRL_CHIL_SET_FORKCHECK		100
+	/* Depending on the value of the (long)i argument, this sets or
+	 * unsets the SimpleForkCheck flag in the CHIL API to enable or
+	 * disable checking and workarounds for applications that fork().
+	 */
+#define ENGINE_CTRL_CHIL_NO_LOCKING		101
+	/* This prevents the initialisation function from providing mutex
+	 * callbacks to the nCipher library. */
+
+/* If an ENGINE supports its own specific control commands and wishes the
+ * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on its
+ * behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN entries
+ * to ENGINE_set_cmd_defns(). It should also implement a ctrl() handler that
+ * supports the stated commands (ie. the "cmd_num" entries as described by the
+ * array). NB: The array must be ordered in increasing order of cmd_num.
+ * "null-terminated" means that the last ENGINE_CMD_DEFN element has cmd_num set
+ * to zero and/or cmd_name set to NULL. */
+typedef struct ENGINE_CMD_DEFN_st
+	{
+	unsigned int cmd_num; /* The command number */
+	const char *cmd_name; /* The command name itself */
+	const char *cmd_desc; /* A short description of the command */
+	unsigned int cmd_flags; /* The input the command expects */
+	} ENGINE_CMD_DEFN;
+
+/* Generic function pointer */
+typedef int (*ENGINE_GEN_FUNC_PTR)(void);
+/* Generic function pointer taking no arguments */
+typedef int (*ENGINE_GEN_INT_FUNC_PTR)(ENGINE *);
+/* Specific control function pointer */
+typedef int (*ENGINE_CTRL_FUNC_PTR)(ENGINE *, int, long, void *, void (*f)(void));
+/* Generic load_key function pointer */
+typedef EVP_PKEY * (*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *,
+	UI_METHOD *ui_method, void *callback_data);
+/* These callback types are for an ENGINE's handler for cipher and digest logic.
+ * These handlers have these prototypes;
+ *   int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid);
+ *   int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid);
+ * Looking at how to implement these handlers in the case of cipher support, if
+ * the framework wants the EVP_CIPHER for 'nid', it will call;
+ *   foo(e, &p_evp_cipher, NULL, nid);    (return zero for failure)
+ * If the framework wants a list of supported 'nid's, it will call;
+ *   foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error)
+ */
+/* Returns to a pointer to the array of supported cipher 'nid's. If the second
+ * parameter is non-NULL it is set to the size of the returned array. */
+typedef int (*ENGINE_CIPHERS_PTR)(ENGINE *, const EVP_CIPHER **, const int **, int);
+typedef int (*ENGINE_DIGESTS_PTR)(ENGINE *, const EVP_MD **, const int **, int);
+
+/* STRUCTURE functions ... all of these functions deal with pointers to ENGINE
+ * structures where the pointers have a "structural reference". This means that
+ * their reference is to allowed access to the structure but it does not imply
+ * that the structure is functional. To simply increment or decrement the
+ * structural reference count, use ENGINE_by_id and ENGINE_free. NB: This is not
+ * required when iterating using ENGINE_get_next as it will automatically
+ * decrement the structural reference count of the "current" ENGINE and
+ * increment the structural reference count of the ENGINE it returns (unless it
+ * is NULL). */
+
+/* Get the first/last "ENGINE" type available. */
+ENGINE *ENGINE_get_first(void);
+ENGINE *ENGINE_get_last(void);
+/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
+ENGINE *ENGINE_get_next(ENGINE *e);
+ENGINE *ENGINE_get_prev(ENGINE *e);
+/* Add another "ENGINE" type into the array. */
+int ENGINE_add(ENGINE *e);
+/* Remove an existing "ENGINE" type from the array. */
+int ENGINE_remove(ENGINE *e);
+/* Retrieve an engine from the list by its unique "id" value. */
+ENGINE *ENGINE_by_id(const char *id);
+/* Add all the built-in engines. */
+void ENGINE_load_openssl(void);
+void ENGINE_load_dynamic(void);
+#ifndef OPENSSL_NO_STATIC_ENGINE
+void ENGINE_load_4758cca(void);
+void ENGINE_load_aep(void);
+void ENGINE_load_atalla(void);
+void ENGINE_load_chil(void);
+void ENGINE_load_cswift(void);
+#ifndef OPENSSL_NO_GMP
+void ENGINE_load_gmp(void);
+#endif
+void ENGINE_load_nuron(void);
+void ENGINE_load_sureware(void);
+void ENGINE_load_ubsec(void);
+#endif
+void ENGINE_load_cryptodev(void);
+void ENGINE_load_padlock(void);
+void ENGINE_load_builtin_engines(void);
+
+/* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
+ * "registry" handling. */
+unsigned int ENGINE_get_table_flags(void);
+void ENGINE_set_table_flags(unsigned int flags);
+
+/* Manage registration of ENGINEs per "table". For each type, there are 3
+ * functions;
+ *   ENGINE_register_***(e) - registers the implementation from 'e' (if it has one)
+ *   ENGINE_unregister_***(e) - unregister the implementation from 'e'
+ *   ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list
+ * Cleanup is automatically registered from each table when required, so
+ * ENGINE_cleanup() will reverse any "register" operations. */
+
+int ENGINE_register_RSA(ENGINE *e);
+void ENGINE_unregister_RSA(ENGINE *e);
+void ENGINE_register_all_RSA(void);
+
+int ENGINE_register_DSA(ENGINE *e);
+void ENGINE_unregister_DSA(ENGINE *e);
+void ENGINE_register_all_DSA(void);
+
+int ENGINE_register_ECDH(ENGINE *e);
+void ENGINE_unregister_ECDH(ENGINE *e);
+void ENGINE_register_all_ECDH(void);
+
+int ENGINE_register_ECDSA(ENGINE *e);
+void ENGINE_unregister_ECDSA(ENGINE *e);
+void ENGINE_register_all_ECDSA(void);
+
+int ENGINE_register_DH(ENGINE *e);
+void ENGINE_unregister_DH(ENGINE *e);
+void ENGINE_register_all_DH(void);
+
+int ENGINE_register_RAND(ENGINE *e);
+void ENGINE_unregister_RAND(ENGINE *e);
+void ENGINE_register_all_RAND(void);
+
+int ENGINE_register_STORE(ENGINE *e);
+void ENGINE_unregister_STORE(ENGINE *e);
+void ENGINE_register_all_STORE(void);
+
+int ENGINE_register_ciphers(ENGINE *e);
+void ENGINE_unregister_ciphers(ENGINE *e);
+void ENGINE_register_all_ciphers(void);
+
+int ENGINE_register_digests(ENGINE *e);
+void ENGINE_unregister_digests(ENGINE *e);
+void ENGINE_register_all_digests(void);
+
+/* These functions register all support from the above categories. Note, use of
+ * these functions can result in static linkage of code your application may not
+ * need. If you only need a subset of functionality, consider using more
+ * selective initialisation. */
+int ENGINE_register_complete(ENGINE *e);
+int ENGINE_register_all_complete(void);
+
+/* Send parametrised control commands to the engine. The possibilities to send
+ * down an integer, a pointer to data or a function pointer are provided. Any of
+ * the parameters may or may not be NULL, depending on the command number. In
+ * actuality, this function only requires a structural (rather than functional)
+ * reference to an engine, but many control commands may require the engine be
+ * functional. The caller should be aware of trying commands that require an
+ * operational ENGINE, and only use functional references in such situations. */
+int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
+
+/* This function tests if an ENGINE-specific command is usable as a "setting".
+ * Eg. in an application's config file that gets processed through
+ * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to
+ * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). */
+int ENGINE_cmd_is_executable(ENGINE *e, int cmd);
+
+/* This function works like ENGINE_ctrl() with the exception of taking a
+ * command name instead of a command number, and can handle optional commands.
+ * See the comment on ENGINE_ctrl_cmd_string() for an explanation on how to
+ * use the cmd_name and cmd_optional. */
+int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name,
+        long i, void *p, void (*f)(void), int cmd_optional);
+
+/* This function passes a command-name and argument to an ENGINE. The cmd_name
+ * is converted to a command number and the control command is called using
+ * 'arg' as an argument (unless the ENGINE doesn't support such a command, in
+ * which case no control command is called). The command is checked for input
+ * flags, and if necessary the argument will be converted to a numeric value. If
+ * cmd_optional is non-zero, then if the ENGINE doesn't support the given
+ * cmd_name the return value will be success anyway. This function is intended
+ * for applications to use so that users (or config files) can supply
+ * engine-specific config data to the ENGINE at run-time to control behaviour of
+ * specific engines. As such, it shouldn't be used for calling ENGINE_ctrl()
+ * functions that return data, deal with binary data, or that are otherwise
+ * supposed to be used directly through ENGINE_ctrl() in application code. Any
+ * "return" data from an ENGINE_ctrl() operation in this function will be lost -
+ * the return value is interpreted as failure if the return value is zero,
+ * success otherwise, and this function returns a boolean value as a result. In
+ * other words, vendors of 'ENGINE'-enabled devices should write ENGINE
+ * implementations with parameterisations that work in this scheme, so that
+ * compliant ENGINE-based applications can work consistently with the same
+ * configuration for the same ENGINE-enabled devices, across applications. */
+int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg,
+				int cmd_optional);
+
+/* These functions are useful for manufacturing new ENGINE structures. They
+ * don't address reference counting at all - one uses them to populate an ENGINE
+ * structure with personalised implementations of things prior to using it
+ * directly or adding it to the builtin ENGINE list in OpenSSL. These are also
+ * here so that the ENGINE structure doesn't have to be exposed and break binary
+ * compatibility! */
+ENGINE *ENGINE_new(void);
+int ENGINE_free(ENGINE *e);
+int ENGINE_up_ref(ENGINE *e);
+int ENGINE_set_id(ENGINE *e, const char *id);
+int ENGINE_set_name(ENGINE *e, const char *name);
+int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth);
+int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth);
+int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth);
+int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth);
+int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth);
+int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth);
+int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth);
+int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f);
+int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f);
+int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f);
+int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f);
+int ENGINE_set_load_privkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpriv_f);
+int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f);
+int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f);
+int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f);
+int ENGINE_set_flags(ENGINE *e, int flags);
+int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns);
+/* These functions allow control over any per-structure ENGINE data. */
+int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+		CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg);
+void *ENGINE_get_ex_data(const ENGINE *e, int idx);
+
+/* This function cleans up anything that needs it. Eg. the ENGINE_add() function
+ * automatically ensures the list cleanup function is registered to be called
+ * from ENGINE_cleanup(). Similarly, all ENGINE_register_*** functions ensure
+ * ENGINE_cleanup() will clean up after them. */
+void ENGINE_cleanup(void);
+
+/* These return values from within the ENGINE structure. These can be useful
+ * with functional references as well as structural references - it depends
+ * which you obtained. Using the result for functional purposes if you only
+ * obtained a structural reference may be problematic! */
+const char *ENGINE_get_id(const ENGINE *e);
+const char *ENGINE_get_name(const ENGINE *e);
+const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e);
+const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e);
+const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e);
+const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e);
+const DH_METHOD *ENGINE_get_DH(const ENGINE *e);
+const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e);
+const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e);
+ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e);
+ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e);
+ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e);
+ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e);
+ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e);
+const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid);
+const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid);
+const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e);
+int ENGINE_get_flags(const ENGINE *e);
+
+/* FUNCTIONAL functions. These functions deal with ENGINE structures
+ * that have (or will) be initialised for use. Broadly speaking, the
+ * structural functions are useful for iterating the list of available
+ * engine types, creating new engine types, and other "list" operations.
+ * These functions actually deal with ENGINEs that are to be used. As
+ * such these functions can fail (if applicable) when particular
+ * engines are unavailable - eg. if a hardware accelerator is not
+ * attached or not functioning correctly. Each ENGINE has 2 reference
+ * counts; structural and functional. Every time a functional reference
+ * is obtained or released, a corresponding structural reference is
+ * automatically obtained or released too. */
+
+/* Initialise a engine type for use (or up its reference count if it's
+ * already in use). This will fail if the engine is not currently
+ * operational and cannot initialise. */
+int ENGINE_init(ENGINE *e);
+/* Free a functional reference to a engine type. This does not require
+ * a corresponding call to ENGINE_free as it also releases a structural
+ * reference. */
+int ENGINE_finish(ENGINE *e);
+
+/* The following functions handle keys that are stored in some secondary
+ * location, handled by the engine.  The storage may be on a card or
+ * whatever. */
+EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id,
+	UI_METHOD *ui_method, void *callback_data);
+
+/* This returns a pointer for the current ENGINE structure that
+ * is (by default) performing any RSA operations. The value returned
+ * is an incremented reference, so it should be free'd (ENGINE_finish)
+ * before it is discarded. */
+ENGINE *ENGINE_get_default_RSA(void);
+/* Same for the other "methods" */
+ENGINE *ENGINE_get_default_DSA(void);
+ENGINE *ENGINE_get_default_ECDH(void);
+ENGINE *ENGINE_get_default_ECDSA(void);
+ENGINE *ENGINE_get_default_DH(void);
+ENGINE *ENGINE_get_default_RAND(void);
+/* These functions can be used to get a functional reference to perform
+ * ciphering or digesting corresponding to "nid". */
+ENGINE *ENGINE_get_cipher_engine(int nid);
+ENGINE *ENGINE_get_digest_engine(int nid);
+
+/* This sets a new default ENGINE structure for performing RSA
+ * operations. If the result is non-zero (success) then the ENGINE
+ * structure will have had its reference count up'd so the caller
+ * should still free their own reference 'e'. */
+int ENGINE_set_default_RSA(ENGINE *e);
+int ENGINE_set_default_string(ENGINE *e, const char *def_list);
+/* Same for the other "methods" */
+int ENGINE_set_default_DSA(ENGINE *e);
+int ENGINE_set_default_ECDH(ENGINE *e);
+int ENGINE_set_default_ECDSA(ENGINE *e);
+int ENGINE_set_default_DH(ENGINE *e);
+int ENGINE_set_default_RAND(ENGINE *e);
+int ENGINE_set_default_ciphers(ENGINE *e);
+int ENGINE_set_default_digests(ENGINE *e);
+
+/* The combination "set" - the flags are bitwise "OR"d from the
+ * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()"
+ * function, this function can result in unnecessary static linkage. If your
+ * application requires only specific functionality, consider using more
+ * selective functions. */
+int ENGINE_set_default(ENGINE *e, unsigned int flags);
+
+void ENGINE_add_conf_module(void);
+
+/* Deprecated functions ... */
+/* int ENGINE_clear_defaults(void); */
+
+/**************************/
+/* DYNAMIC ENGINE SUPPORT */
+/**************************/
+
+/* Binary/behaviour compatibility levels */
+#define OSSL_DYNAMIC_VERSION		(unsigned long)0x00020000
+/* Binary versions older than this are too old for us (whether we're a loader or
+ * a loadee) */
+#define OSSL_DYNAMIC_OLDEST		(unsigned long)0x00020000
+
+/* When compiling an ENGINE entirely as an external shared library, loadable by
+ * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
+ * type provides the calling application's (or library's) error functionality
+ * and memory management function pointers to the loaded library. These should
+ * be used/set in the loaded library code so that the loading application's
+ * 'state' will be used/changed in all operations. The 'static_state' pointer
+ * allows the loaded library to know if it shares the same static data as the
+ * calling application (or library), and thus whether these callbacks need to be
+ * set or not. */
+typedef void *(*dyn_MEM_malloc_cb)(size_t);
+typedef void *(*dyn_MEM_realloc_cb)(void *, size_t);
+typedef void (*dyn_MEM_free_cb)(void *);
+typedef struct st_dynamic_MEM_fns {
+	dyn_MEM_malloc_cb			malloc_cb;
+	dyn_MEM_realloc_cb			realloc_cb;
+	dyn_MEM_free_cb				free_cb;
+	} dynamic_MEM_fns;
+/* FIXME: Perhaps the memory and locking code (crypto.h) should declare and use
+ * these types so we (and any other dependant code) can simplify a bit?? */
+typedef void (*dyn_lock_locking_cb)(int,int,const char *,int);
+typedef int (*dyn_lock_add_lock_cb)(int*,int,int,const char *,int);
+typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb)(
+						const char *,int);
+typedef void (*dyn_dynlock_lock_cb)(int,struct CRYPTO_dynlock_value *,
+						const char *,int);
+typedef void (*dyn_dynlock_destroy_cb)(struct CRYPTO_dynlock_value *,
+						const char *,int);
+typedef struct st_dynamic_LOCK_fns {
+	dyn_lock_locking_cb			lock_locking_cb;
+	dyn_lock_add_lock_cb			lock_add_lock_cb;
+	dyn_dynlock_create_cb			dynlock_create_cb;
+	dyn_dynlock_lock_cb			dynlock_lock_cb;
+	dyn_dynlock_destroy_cb			dynlock_destroy_cb;
+	} dynamic_LOCK_fns;
+/* The top-level structure */
+typedef struct st_dynamic_fns {
+	void 					*static_state;
+	const ERR_FNS				*err_fns;
+	const CRYPTO_EX_DATA_IMPL		*ex_data_fns;
+	dynamic_MEM_fns				mem_fns;
+	dynamic_LOCK_fns			lock_fns;
+	} dynamic_fns;
+
+/* The version checking function should be of this prototype. NB: The
+ * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading code.
+ * If this function returns zero, it indicates a (potential) version
+ * incompatibility and the loaded library doesn't believe it can proceed.
+ * Otherwise, the returned value is the (latest) version supported by the
+ * loading library. The loader may still decide that the loaded code's version
+ * is unsatisfactory and could veto the load. The function is expected to
+ * be implemented with the symbol name "v_check", and a default implementation
+ * can be fully instantiated with IMPLEMENT_DYNAMIC_CHECK_FN(). */
+typedef unsigned long (*dynamic_v_check_fn)(unsigned long ossl_version);
+#define IMPLEMENT_DYNAMIC_CHECK_FN() \
+	unsigned long v_check(unsigned long v) { \
+		if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \
+		return 0; }
+
+/* This function is passed the ENGINE structure to initialise with its own
+ * function and command settings. It should not adjust the structural or
+ * functional reference counts. If this function returns zero, (a) the load will
+ * be aborted, (b) the previous ENGINE state will be memcpy'd back onto the
+ * structure, and (c) the shared library will be unloaded. So implementations
+ * should do their own internal cleanup in failure circumstances otherwise they
+ * could leak. The 'id' parameter, if non-NULL, represents the ENGINE id that
+ * the loader is looking for. If this is NULL, the shared library can choose to
+ * return failure or to initialise a 'default' ENGINE. If non-NULL, the shared
+ * library must initialise only an ENGINE matching the passed 'id'. The function
+ * is expected to be implemented with the symbol name "bind_engine". A standard
+ * implementation can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where
+ * the parameter 'fn' is a callback function that populates the ENGINE structure
+ * and returns an int value (zero for failure). 'fn' should have prototype;
+ *    [static] int fn(ENGINE *e, const char *id); */
+typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
+				const dynamic_fns *fns);
+#define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
+	int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
+		if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \
+		if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
+			fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
+			return 0; \
+		CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
+		CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
+		CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
+		CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
+		CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
+		if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
+			return 0; \
+		if(!ERR_set_implementation(fns->err_fns)) return 0; \
+	skip_cbs: \
+		if(!fn(e,id)) return 0; \
+		return 1; }
+
+/* If the loading application (or library) and the loaded ENGINE library share
+ * the same static data (eg. they're both dynamically linked to the same
+ * libcrypto.so) we need a way to avoid trying to set system callbacks - this
+ * would fail, and for the same reason that it's unnecessary to try. If the
+ * loaded ENGINE has (or gets from through the loader) its own copy of the
+ * libcrypto static data, we will need to set the callbacks. The easiest way to
+ * detect this is to have a function that returns a pointer to some static data
+ * and let the loading application and loaded ENGINE compare their respective
+ * values. */
+void *ENGINE_get_static_state(void);
+
+#if defined(__OpenBSD__) || defined(__FreeBSD__)
+void ENGINE_setup_bsd_cryptodev(void);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_ENGINE_strings(void);
+
+/* Error codes for the ENGINE functions. */
+
+/* Function codes. */
+#define ENGINE_F_DYNAMIC_CTRL				 180
+#define ENGINE_F_DYNAMIC_GET_DATA_CTX			 181
+#define ENGINE_F_DYNAMIC_LOAD				 182
+#define ENGINE_F_DYNAMIC_SET_DATA_CTX			 183
+#define ENGINE_F_ENGINE_ADD				 105
+#define ENGINE_F_ENGINE_BY_ID				 106
+#define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE		 170
+#define ENGINE_F_ENGINE_CTRL				 142
+#define ENGINE_F_ENGINE_CTRL_CMD			 178
+#define ENGINE_F_ENGINE_CTRL_CMD_STRING			 171
+#define ENGINE_F_ENGINE_FINISH				 107
+#define ENGINE_F_ENGINE_FREE_UTIL			 108
+#define ENGINE_F_ENGINE_GET_CIPHER			 185
+#define ENGINE_F_ENGINE_GET_DEFAULT_TYPE		 177
+#define ENGINE_F_ENGINE_GET_DIGEST			 186
+#define ENGINE_F_ENGINE_GET_NEXT			 115
+#define ENGINE_F_ENGINE_GET_PREV			 116
+#define ENGINE_F_ENGINE_INIT				 119
+#define ENGINE_F_ENGINE_LIST_ADD			 120
+#define ENGINE_F_ENGINE_LIST_REMOVE			 121
+#define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY		 150
+#define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY			 151
+#define ENGINE_F_ENGINE_NEW				 122
+#define ENGINE_F_ENGINE_REMOVE				 123
+#define ENGINE_F_ENGINE_SET_DEFAULT_STRING		 189
+#define ENGINE_F_ENGINE_SET_DEFAULT_TYPE		 126
+#define ENGINE_F_ENGINE_SET_ID				 129
+#define ENGINE_F_ENGINE_SET_NAME			 130
+#define ENGINE_F_ENGINE_TABLE_REGISTER			 184
+#define ENGINE_F_ENGINE_UNLOAD_KEY			 152
+#define ENGINE_F_ENGINE_UNLOCKED_FINISH			 191
+#define ENGINE_F_ENGINE_UP_REF				 190
+#define ENGINE_F_INT_CTRL_HELPER			 172
+#define ENGINE_F_INT_ENGINE_CONFIGURE			 188
+#define ENGINE_F_INT_ENGINE_MODULE_INIT			 187
+#define ENGINE_F_LOG_MESSAGE				 141
+
+/* Reason codes. */
+#define ENGINE_R_ALREADY_LOADED				 100
+#define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER		 133
+#define ENGINE_R_CMD_NOT_EXECUTABLE			 134
+#define ENGINE_R_COMMAND_TAKES_INPUT			 135
+#define ENGINE_R_COMMAND_TAKES_NO_INPUT			 136
+#define ENGINE_R_CONFLICTING_ENGINE_ID			 103
+#define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED		 119
+#define ENGINE_R_DH_NOT_IMPLEMENTED			 139
+#define ENGINE_R_DSA_NOT_IMPLEMENTED			 140
+#define ENGINE_R_DSO_FAILURE				 104
+#define ENGINE_R_DSO_NOT_FOUND				 132
+#define ENGINE_R_ENGINES_SECTION_ERROR			 148
+#define ENGINE_R_ENGINE_IS_NOT_IN_LIST			 105
+#define ENGINE_R_ENGINE_SECTION_ERROR			 149
+#define ENGINE_R_FAILED_LOADING_PRIVATE_KEY		 128
+#define ENGINE_R_FAILED_LOADING_PUBLIC_KEY		 129
+#define ENGINE_R_FINISH_FAILED				 106
+#define ENGINE_R_GET_HANDLE_FAILED			 107
+#define ENGINE_R_ID_OR_NAME_MISSING			 108
+#define ENGINE_R_INIT_FAILED				 109
+#define ENGINE_R_INTERNAL_LIST_ERROR			 110
+#define ENGINE_R_INVALID_ARGUMENT			 143
+#define ENGINE_R_INVALID_CMD_NAME			 137
+#define ENGINE_R_INVALID_CMD_NUMBER			 138
+#define ENGINE_R_INVALID_INIT_VALUE			 151
+#define ENGINE_R_INVALID_STRING				 150
+#define ENGINE_R_NOT_INITIALISED			 117
+#define ENGINE_R_NOT_LOADED				 112
+#define ENGINE_R_NO_CONTROL_FUNCTION			 120
+#define ENGINE_R_NO_INDEX				 144
+#define ENGINE_R_NO_LOAD_FUNCTION			 125
+#define ENGINE_R_NO_REFERENCE				 130
+#define ENGINE_R_NO_SUCH_ENGINE				 116
+#define ENGINE_R_NO_UNLOAD_FUNCTION			 126
+#define ENGINE_R_PROVIDE_PARAMETERS			 113
+#define ENGINE_R_RSA_NOT_IMPLEMENTED			 141
+#define ENGINE_R_UNIMPLEMENTED_CIPHER			 146
+#define ENGINE_R_UNIMPLEMENTED_DIGEST			 147
+#define ENGINE_R_VERSION_INCOMPATIBILITY		 145
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/err.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/err.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/err.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,318 @@
+/* crypto/err/err.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ERR_H
+#define HEADER_ERR_H
+
+#include <openssl/e_os2.h>
+
+#ifndef OPENSSL_NO_FP_API
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#ifndef OPENSSL_NO_LHASH
+#include <openssl/lhash.h>
+#endif
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifndef OPENSSL_NO_ERR
+#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,d,e)
+#else
+#define ERR_PUT_error(a,b,c,d,e)	ERR_put_error(a,b,c,NULL,0)
+#endif
+
+#include <errno.h>
+
+#define ERR_TXT_MALLOCED	0x01
+#define ERR_TXT_STRING		0x02
+
+#define ERR_FLAG_MARK		0x01
+
+#define ERR_NUM_ERRORS	16
+typedef struct err_state_st
+	{
+	unsigned long pid;
+	int err_flags[ERR_NUM_ERRORS];
+	unsigned long err_buffer[ERR_NUM_ERRORS];
+	char *err_data[ERR_NUM_ERRORS];
+	int err_data_flags[ERR_NUM_ERRORS];
+	const char *err_file[ERR_NUM_ERRORS];
+	int err_line[ERR_NUM_ERRORS];
+	int top,bottom;
+	} ERR_STATE;
+
+/* library */
+#define ERR_LIB_NONE		1
+#define ERR_LIB_SYS		2
+#define ERR_LIB_BN		3
+#define ERR_LIB_RSA		4
+#define ERR_LIB_DH		5
+#define ERR_LIB_EVP		6
+#define ERR_LIB_BUF		7
+#define ERR_LIB_OBJ		8
+#define ERR_LIB_PEM		9
+#define ERR_LIB_DSA		10
+#define ERR_LIB_X509		11
+/* #define ERR_LIB_METH         12 */
+#define ERR_LIB_ASN1		13
+#define ERR_LIB_CONF		14
+#define ERR_LIB_CRYPTO		15
+#define ERR_LIB_EC		16
+#define ERR_LIB_SSL		20
+/* #define ERR_LIB_SSL23        21 */
+/* #define ERR_LIB_SSL2         22 */
+/* #define ERR_LIB_SSL3         23 */
+/* #define ERR_LIB_RSAREF       30 */
+/* #define ERR_LIB_PROXY        31 */
+#define ERR_LIB_BIO		32
+#define ERR_LIB_PKCS7		33
+#define ERR_LIB_X509V3		34
+#define ERR_LIB_PKCS12		35
+#define ERR_LIB_RAND		36
+#define ERR_LIB_DSO		37
+#define ERR_LIB_ENGINE		38
+#define ERR_LIB_OCSP            39
+#define ERR_LIB_UI              40
+#define ERR_LIB_COMP            41
+#define ERR_LIB_ECDSA		42
+#define ERR_LIB_ECDH		43
+#define ERR_LIB_STORE           44
+
+#define ERR_LIB_USER		128
+
+#define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__)
+#define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__)
+#define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__)
+#define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__)
+#define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__)
+#define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__)
+#define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__)
+#define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__)
+#define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__)
+#define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__)
+#define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__)
+#define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__)
+#define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__)
+#define ECerr(f,r)   ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__)
+#define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__)
+#define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__)
+#define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__)
+#define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__)
+#define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__)
+#define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__)
+#define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__)
+#define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__)
+#define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__)
+#define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__)
+#define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__)
+#define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__)
+#define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__)
+#define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__)
+
+/* Borland C seems too stupid to be able to shift and do longs in
+ * the pre-processor :-( */
+#define ERR_PACK(l,f,r)		(((((unsigned long)l)&0xffL)*0x1000000)| \
+				((((unsigned long)f)&0xfffL)*0x1000)| \
+				((((unsigned long)r)&0xfffL)))
+#define ERR_GET_LIB(l)		(int)((((unsigned long)l)>>24L)&0xffL)
+#define ERR_GET_FUNC(l)		(int)((((unsigned long)l)>>12L)&0xfffL)
+#define ERR_GET_REASON(l)	(int)((l)&0xfffL)
+#define ERR_FATAL_ERROR(l)	(int)((l)&ERR_R_FATAL)
+
+
+/* OS functions */
+#define SYS_F_FOPEN		1
+#define SYS_F_CONNECT		2
+#define SYS_F_GETSERVBYNAME	3
+#define SYS_F_SOCKET		4
+#define SYS_F_IOCTLSOCKET	5
+#define SYS_F_BIND		6
+#define SYS_F_LISTEN		7
+#define SYS_F_ACCEPT		8
+#define SYS_F_WSASTARTUP	9 /* Winsock stuff */
+#define SYS_F_OPENDIR		10
+#define SYS_F_FREAD		11
+
+
+/* reasons */
+#define ERR_R_SYS_LIB	ERR_LIB_SYS       /* 2 */
+#define ERR_R_BN_LIB	ERR_LIB_BN        /* 3 */
+#define ERR_R_RSA_LIB	ERR_LIB_RSA       /* 4 */
+#define ERR_R_DH_LIB	ERR_LIB_DH        /* 5 */
+#define ERR_R_EVP_LIB	ERR_LIB_EVP       /* 6 */
+#define ERR_R_BUF_LIB	ERR_LIB_BUF       /* 7 */
+#define ERR_R_OBJ_LIB	ERR_LIB_OBJ       /* 8 */
+#define ERR_R_PEM_LIB	ERR_LIB_PEM       /* 9 */
+#define ERR_R_DSA_LIB	ERR_LIB_DSA      /* 10 */
+#define ERR_R_X509_LIB	ERR_LIB_X509     /* 11 */
+#define ERR_R_ASN1_LIB	ERR_LIB_ASN1     /* 13 */
+#define ERR_R_CONF_LIB	ERR_LIB_CONF     /* 14 */
+#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO  /* 15 */
+#define ERR_R_EC_LIB	ERR_LIB_EC       /* 16 */
+#define ERR_R_SSL_LIB	ERR_LIB_SSL      /* 20 */
+#define ERR_R_BIO_LIB	ERR_LIB_BIO      /* 32 */
+#define ERR_R_PKCS7_LIB	ERR_LIB_PKCS7    /* 33 */
+#define ERR_R_X509V3_LIB ERR_LIB_X509V3  /* 34 */
+#define ERR_R_PKCS12_LIB ERR_LIB_PKCS12  /* 35 */
+#define ERR_R_RAND_LIB	ERR_LIB_RAND     /* 36 */
+#define ERR_R_DSO_LIB	ERR_LIB_DSO      /* 37 */
+#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE  /* 38 */
+#define ERR_R_OCSP_LIB  ERR_LIB_OCSP     /* 39 */
+#define ERR_R_UI_LIB    ERR_LIB_UI       /* 40 */
+#define ERR_R_COMP_LIB	ERR_LIB_COMP     /* 41 */
+#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA	 /* 42 */
+#define ERR_R_ECDH_LIB  ERR_LIB_ECDH	 /* 43 */
+#define ERR_R_STORE_LIB ERR_LIB_STORE    /* 44 */
+
+#define ERR_R_NESTED_ASN1_ERROR			58
+#define ERR_R_BAD_ASN1_OBJECT_HEADER		59
+#define ERR_R_BAD_GET_ASN1_OBJECT_CALL		60
+#define ERR_R_EXPECTING_AN_ASN1_SEQUENCE	61
+#define ERR_R_ASN1_LENGTH_MISMATCH		62
+#define ERR_R_MISSING_ASN1_EOS			63
+
+/* fatal error */
+#define ERR_R_FATAL				64
+#define	ERR_R_MALLOC_FAILURE			(1|ERR_R_FATAL)
+#define	ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED	(2|ERR_R_FATAL)
+#define	ERR_R_PASSED_NULL_PARAMETER		(3|ERR_R_FATAL)
+#define	ERR_R_INTERNAL_ERROR			(4|ERR_R_FATAL)
+#define	ERR_R_DISABLED				(5|ERR_R_FATAL)
+
+/* 99 is the maximum possible ERR_R_... code, higher values
+ * are reserved for the individual libraries */
+
+
+typedef struct ERR_string_data_st
+	{
+	unsigned long error;
+	const char *string;
+	} ERR_STRING_DATA;
+
+void ERR_put_error(int lib, int func,int reason,const char *file,int line);
+void ERR_set_error_data(char *data,int flags);
+
+unsigned long ERR_get_error(void);
+unsigned long ERR_get_error_line(const char **file,int *line);
+unsigned long ERR_get_error_line_data(const char **file,int *line,
+				      const char **data, int *flags);
+unsigned long ERR_peek_error(void);
+unsigned long ERR_peek_error_line(const char **file,int *line);
+unsigned long ERR_peek_error_line_data(const char **file,int *line,
+				       const char **data,int *flags);
+unsigned long ERR_peek_last_error(void);
+unsigned long ERR_peek_last_error_line(const char **file,int *line);
+unsigned long ERR_peek_last_error_line_data(const char **file,int *line,
+				       const char **data,int *flags);
+void ERR_clear_error(void );
+char *ERR_error_string(unsigned long e,char *buf);
+void ERR_error_string_n(unsigned long e, char *buf, size_t len);
+const char *ERR_lib_error_string(unsigned long e);
+const char *ERR_func_error_string(unsigned long e);
+const char *ERR_reason_error_string(unsigned long e);
+void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
+			 void *u);
+#ifndef OPENSSL_NO_FP_API
+void ERR_print_errors_fp(FILE *fp);
+#endif
+#ifndef OPENSSL_NO_BIO
+void ERR_print_errors(BIO *bp);
+void ERR_add_error_data(int num, ...);
+#endif
+void ERR_load_strings(int lib,ERR_STRING_DATA str[]);
+void ERR_unload_strings(int lib,ERR_STRING_DATA str[]);
+void ERR_load_ERR_strings(void);
+void ERR_load_crypto_strings(void);
+void ERR_free_strings(void);
+
+void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+ERR_STATE *ERR_get_state(void);
+
+#ifndef OPENSSL_NO_LHASH
+LHASH *ERR_get_string_table(void);
+LHASH *ERR_get_err_state_table(void);
+void ERR_release_err_state_table(LHASH **hash);
+#endif
+
+int ERR_get_next_error_library(void);
+
+int ERR_set_mark(void);
+int ERR_pop_to_mark(void);
+
+/* Already defined in ossl_typ.h */
+/* typedef struct st_ERR_FNS ERR_FNS; */
+/* An application can use this function and provide the return value to loaded
+ * modules that should use the application's ERR state/functionality */
+const ERR_FNS *ERR_get_implementation(void);
+/* A loaded module should call this function prior to any ERR operations using
+ * the application's "ERR_FNS". */
+int ERR_set_implementation(const ERR_FNS *fns);
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/evp.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/evp.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/evp.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,939 @@
+/* crypto/evp/evp.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_ENVELOPE_H
+#define HEADER_ENVELOPE_H
+
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# include <openssl/opensslconf.h>
+#else
+# define OPENSSL_ALGORITHM_DEFINES
+# include <openssl/opensslconf.h>
+# undef OPENSSL_ALGORITHM_DEFINES
+#endif
+
+#include <openssl/ossl_typ.h>
+
+#include <openssl/symhacks.h>
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+
+/*
+#define EVP_RC2_KEY_SIZE		16
+#define EVP_RC4_KEY_SIZE		16
+#define EVP_BLOWFISH_KEY_SIZE		16
+#define EVP_CAST5_KEY_SIZE		16
+#define EVP_RC5_32_12_16_KEY_SIZE	16
+*/
+#define EVP_MAX_MD_SIZE			64	/* longest known is SHA512 */
+#define EVP_MAX_KEY_LENGTH		32
+#define EVP_MAX_IV_LENGTH		16
+#define EVP_MAX_BLOCK_LENGTH		32
+
+#define PKCS5_SALT_LEN			8
+/* Default PKCS#5 iteration count */
+#define PKCS5_DEFAULT_ITER		2048
+
+#include <openssl/objects.h>
+
+#define EVP_PK_RSA	0x0001
+#define EVP_PK_DSA	0x0002
+#define EVP_PK_DH	0x0004
+#define EVP_PK_EC	0x0008
+#define EVP_PKT_SIGN	0x0010
+#define EVP_PKT_ENC	0x0020
+#define EVP_PKT_EXCH	0x0040
+#define EVP_PKS_RSA	0x0100
+#define EVP_PKS_DSA	0x0200
+#define EVP_PKS_EC	0x0400
+#define EVP_PKT_EXP	0x1000 /* <= 512 bit key */
+
+#define EVP_PKEY_NONE	NID_undef
+#define EVP_PKEY_RSA	NID_rsaEncryption
+#define EVP_PKEY_RSA2	NID_rsa
+#define EVP_PKEY_DSA	NID_dsa
+#define EVP_PKEY_DSA1	NID_dsa_2
+#define EVP_PKEY_DSA2	NID_dsaWithSHA
+#define EVP_PKEY_DSA3	NID_dsaWithSHA1
+#define EVP_PKEY_DSA4	NID_dsaWithSHA1_2
+#define EVP_PKEY_DH	NID_dhKeyAgreement
+#define EVP_PKEY_EC	NID_X9_62_id_ecPublicKey
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* Type needs to be a bit field
+ * Sub-type needs to be for variations on the method, as in, can it do
+ * arbitrary encryption.... */
+struct evp_pkey_st
+	{
+	int type;
+	int save_type;
+	int references;
+	union	{
+		char *ptr;
+#ifndef OPENSSL_NO_RSA
+		struct rsa_st *rsa;	/* RSA */
+#endif
+#ifndef OPENSSL_NO_DSA
+		struct dsa_st *dsa;	/* DSA */
+#endif
+#ifndef OPENSSL_NO_DH
+		struct dh_st *dh;	/* DH */
+#endif
+#ifndef OPENSSL_NO_EC
+		struct ec_key_st *ec;	/* ECC */
+#endif
+		} pkey;
+	int save_parameters;
+	STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+	} /* EVP_PKEY */;
+
+#define EVP_PKEY_MO_SIGN	0x0001
+#define EVP_PKEY_MO_VERIFY	0x0002
+#define EVP_PKEY_MO_ENCRYPT	0x0004
+#define EVP_PKEY_MO_DECRYPT	0x0008
+
+#if 0
+/* This structure is required to tie the message digest and signing together.
+ * The lookup can be done by md/pkey_method, oid, oid/pkey_method, or
+ * oid, md and pkey.
+ * This is required because for various smart-card perform the digest and
+ * signing/verification on-board.  To handle this case, the specific
+ * EVP_MD and EVP_PKEY_METHODs need to be closely associated.
+ * When a PKEY is created, it will have a EVP_PKEY_METHOD associated with it.
+ * This can either be software or a token to provide the required low level
+ * routines.
+ */
+typedef struct evp_pkey_md_st
+	{
+	int oid;
+	EVP_MD *md;
+	EVP_PKEY_METHOD *pkey;
+	} EVP_PKEY_MD;
+
+#define EVP_rsa_md2() \
+		EVP_PKEY_MD_add(NID_md2WithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_md2())
+#define EVP_rsa_md5() \
+		EVP_PKEY_MD_add(NID_md5WithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_md5())
+#define EVP_rsa_sha0() \
+		EVP_PKEY_MD_add(NID_shaWithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_sha())
+#define EVP_rsa_sha1() \
+		EVP_PKEY_MD_add(NID_sha1WithRSAEncryption,\
+			EVP_rsa_pkcs1(),EVP_sha1())
+#define EVP_rsa_ripemd160() \
+		EVP_PKEY_MD_add(NID_ripemd160WithRSA,\
+			EVP_rsa_pkcs1(),EVP_ripemd160())
+#define EVP_rsa_mdc2() \
+		EVP_PKEY_MD_add(NID_mdc2WithRSA,\
+			EVP_rsa_octet_string(),EVP_mdc2())
+#define EVP_dsa_sha() \
+		EVP_PKEY_MD_add(NID_dsaWithSHA,\
+			EVP_dsa(),EVP_sha())
+#define EVP_dsa_sha1() \
+		EVP_PKEY_MD_add(NID_dsaWithSHA1,\
+			EVP_dsa(),EVP_sha1())
+
+typedef struct evp_pkey_method_st
+	{
+	char *name;
+	int flags;
+	int type;		/* RSA, DSA, an SSLeay specific constant */
+	int oid;		/* For the pub-key type */
+	int encrypt_oid;	/* pub/priv key encryption */
+
+	int (*sign)();
+	int (*verify)();
+	struct	{
+		int (*set)();	/* get and/or set the underlying type */
+		int (*get)();
+		int (*encrypt)();
+		int (*decrypt)();
+		int (*i2d)();
+		int (*d2i)();
+		int (*dup)();
+		} pub,priv;
+	int (*set_asn1_parameters)();
+	int (*get_asn1_parameters)();
+	} EVP_PKEY_METHOD;
+#endif
+
+#ifndef EVP_MD
+struct env_md_st
+	{
+	int type;
+	int pkey_type;
+	int md_size;
+	unsigned long flags;
+	int (*init)(EVP_MD_CTX *ctx);
+	int (*update)(EVP_MD_CTX *ctx,const void *data,size_t count);
+	int (*final)(EVP_MD_CTX *ctx,unsigned char *md);
+	int (*copy)(EVP_MD_CTX *to,const EVP_MD_CTX *from);
+	int (*cleanup)(EVP_MD_CTX *ctx);
+
+	/* FIXME: prototype these some day */
+	int (*sign)(int type, const unsigned char *m, unsigned int m_length,
+		    unsigned char *sigret, unsigned int *siglen, void *key);
+	int (*verify)(int type, const unsigned char *m, unsigned int m_length,
+		      const unsigned char *sigbuf, unsigned int siglen,
+		      void *key);
+	int required_pkey_type[5]; /*EVP_PKEY_xxx */
+	int block_size;
+	int ctx_size; /* how big does the ctx->md_data need to be */
+	} /* EVP_MD */;
+
+typedef int evp_sign_method(int type,const unsigned char *m,
+			    unsigned int m_length,unsigned char *sigret,
+			    unsigned int *siglen, void *key);
+typedef int evp_verify_method(int type,const unsigned char *m,
+			    unsigned int m_length,const unsigned char *sigbuf,
+			    unsigned int siglen, void *key);
+
+#define EVP_MD_FLAG_ONESHOT	0x0001 /* digest can only handle a single
+					* block */
+
+#define EVP_PKEY_NULL_method	NULL,NULL,{0,0,0,0}
+
+#ifndef OPENSSL_NO_DSA
+#define EVP_PKEY_DSA_method	(evp_sign_method *)DSA_sign, \
+				(evp_verify_method *)DSA_verify, \
+				{EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \
+					EVP_PKEY_DSA4,0}
+#else
+#define EVP_PKEY_DSA_method	EVP_PKEY_NULL_method
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+#define EVP_PKEY_ECDSA_method   (evp_sign_method *)ECDSA_sign, \
+				(evp_verify_method *)ECDSA_verify, \
+                                 {EVP_PKEY_EC,0,0,0}
+#else   
+#define EVP_PKEY_ECDSA_method   EVP_PKEY_NULL_method
+#endif
+
+#ifndef OPENSSL_NO_RSA
+#define EVP_PKEY_RSA_method	(evp_sign_method *)RSA_sign, \
+				(evp_verify_method *)RSA_verify, \
+				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \
+				(evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \
+				(evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \
+				{EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0}
+#else
+#define EVP_PKEY_RSA_method	EVP_PKEY_NULL_method
+#define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method
+#endif
+
+#endif /* !EVP_MD */
+
+struct env_md_ctx_st
+	{
+	const EVP_MD *digest;
+	ENGINE *engine; /* functional reference if 'digest' is ENGINE-provided */
+	unsigned long flags;
+	void *md_data;
+	} /* EVP_MD_CTX */;
+
+/* values for EVP_MD_CTX flags */
+
+#define EVP_MD_CTX_FLAG_ONESHOT		0x0001 /* digest update will be called
+						* once only */
+#define EVP_MD_CTX_FLAG_CLEANED		0x0002 /* context has already been
+						* cleaned */
+#define EVP_MD_CTX_FLAG_REUSE		0x0004 /* Don't free up ctx->md_data
+						* in EVP_MD_CTX_cleanup */
+
+struct evp_cipher_st
+	{
+	int nid;
+	int block_size;
+	int key_len;		/* Default value for variable length ciphers */
+	int iv_len;
+	unsigned long flags;	/* Various flags */
+	int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+		    const unsigned char *iv, int enc);	/* init key */
+	int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
+			 const unsigned char *in, unsigned int inl);/* encrypt/decrypt data */
+	int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
+	int ctx_size;		/* how big ctx->cipher_data needs to be */
+	int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
+	int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
+	int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
+	void *app_data;		/* Application data */
+	} /* EVP_CIPHER */;
+
+/* Values for cipher flags */
+
+/* Modes for ciphers */
+
+#define		EVP_CIPH_STREAM_CIPHER		0x0
+#define		EVP_CIPH_ECB_MODE		0x1
+#define		EVP_CIPH_CBC_MODE		0x2
+#define		EVP_CIPH_CFB_MODE		0x3
+#define		EVP_CIPH_OFB_MODE		0x4
+#define 	EVP_CIPH_MODE			0x7
+/* Set if variable length cipher */
+#define 	EVP_CIPH_VARIABLE_LENGTH	0x8
+/* Set if the iv handling should be done by the cipher itself */
+#define 	EVP_CIPH_CUSTOM_IV		0x10
+/* Set if the cipher's init() function should be called if key is NULL */
+#define 	EVP_CIPH_ALWAYS_CALL_INIT	0x20
+/* Call ctrl() to init cipher parameters */
+#define 	EVP_CIPH_CTRL_INIT		0x40
+/* Don't use standard key length function */
+#define 	EVP_CIPH_CUSTOM_KEY_LENGTH	0x80
+/* Don't use standard block padding */
+#define 	EVP_CIPH_NO_PADDING		0x100
+/* cipher handles random key generation */
+#define 	EVP_CIPH_RAND_KEY		0x200
+
+/* ctrl() values */
+
+#define		EVP_CTRL_INIT			0x0
+#define 	EVP_CTRL_SET_KEY_LENGTH		0x1
+#define 	EVP_CTRL_GET_RC2_KEY_BITS	0x2
+#define 	EVP_CTRL_SET_RC2_KEY_BITS	0x3
+#define 	EVP_CTRL_GET_RC5_ROUNDS		0x4
+#define 	EVP_CTRL_SET_RC5_ROUNDS		0x5
+#define 	EVP_CTRL_RAND_KEY		0x6
+
+typedef struct evp_cipher_info_st
+	{
+	const EVP_CIPHER *cipher;
+	unsigned char iv[EVP_MAX_IV_LENGTH];
+	} EVP_CIPHER_INFO;
+
+struct evp_cipher_ctx_st
+	{
+	const EVP_CIPHER *cipher;
+	ENGINE *engine;	/* functional reference if 'cipher' is ENGINE-provided */
+	int encrypt;		/* encrypt or decrypt */
+	int buf_len;		/* number we have left */
+
+	unsigned char  oiv[EVP_MAX_IV_LENGTH];	/* original iv */
+	unsigned char  iv[EVP_MAX_IV_LENGTH];	/* working iv */
+	unsigned char buf[EVP_MAX_BLOCK_LENGTH];/* saved partial block */
+	int num;				/* used by cfb/ofb mode */
+
+	void *app_data;		/* application stuff */
+	int key_len;		/* May change for variable length cipher */
+	unsigned long flags;	/* Various flags */
+	void *cipher_data; /* per EVP data */
+	int final_used;
+	int block_mask;
+	unsigned char final[EVP_MAX_BLOCK_LENGTH];/* possible final block */
+	} /* EVP_CIPHER_CTX */;
+
+typedef struct evp_Encode_Ctx_st
+	{
+	int num;	/* number saved in a partial encode/decode */
+	int length;	/* The length is either the output line length
+			 * (in input bytes) or the shortest input line
+			 * length that is ok.  Once decoding begins,
+			 * the length is adjusted up each time a longer
+			 * line is decoded */
+	unsigned char enc_data[80];	/* data to encode */
+	int line_num;	/* number read on current line */
+	int expect_nl;
+	} EVP_ENCODE_CTX;
+
+/* Password based encryption function */
+typedef int (EVP_PBE_KEYGEN)(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+		ASN1_TYPE *param, const EVP_CIPHER *cipher,
+                const EVP_MD *md, int en_de);
+
+#ifndef OPENSSL_NO_RSA
+#define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
+					(char *)(rsa))
+#endif
+
+#ifndef OPENSSL_NO_DSA
+#define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
+					(char *)(dsa))
+#endif
+
+#ifndef OPENSSL_NO_DH
+#define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\
+					(char *)(dh))
+#endif
+
+#ifndef OPENSSL_NO_EC
+#define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\
+                                        (char *)(eckey))
+#endif
+
+/* Add some extra combinations */
+#define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a))
+#define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a))
+#define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a))
+#define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a))
+
+#define EVP_MD_type(e)			((e)->type)
+#define EVP_MD_nid(e)			EVP_MD_type(e)
+#define EVP_MD_name(e)			OBJ_nid2sn(EVP_MD_nid(e))
+#define EVP_MD_pkey_type(e)		((e)->pkey_type)
+#define EVP_MD_size(e)			((e)->md_size)
+#define EVP_MD_block_size(e)		((e)->block_size)
+
+#define EVP_MD_CTX_md(e)		((e)->digest)
+#define EVP_MD_CTX_size(e)		EVP_MD_size((e)->digest)
+#define EVP_MD_CTX_block_size(e)	EVP_MD_block_size((e)->digest)
+#define EVP_MD_CTX_type(e)		EVP_MD_type((e)->digest)
+
+#define EVP_CIPHER_nid(e)		((e)->nid)
+#define EVP_CIPHER_name(e)		OBJ_nid2sn(EVP_CIPHER_nid(e))
+#define EVP_CIPHER_block_size(e)	((e)->block_size)
+#define EVP_CIPHER_key_length(e)	((e)->key_len)
+#define EVP_CIPHER_iv_length(e)		((e)->iv_len)
+#define EVP_CIPHER_flags(e)		((e)->flags)
+#define EVP_CIPHER_mode(e)		(((e)->flags) & EVP_CIPH_MODE)
+
+#define EVP_CIPHER_CTX_cipher(e)	((e)->cipher)
+#define EVP_CIPHER_CTX_nid(e)		((e)->cipher->nid)
+#define EVP_CIPHER_CTX_block_size(e)	((e)->cipher->block_size)
+#define EVP_CIPHER_CTX_key_length(e)	((e)->key_len)
+#define EVP_CIPHER_CTX_iv_length(e)	((e)->cipher->iv_len)
+#define EVP_CIPHER_CTX_get_app_data(e)	((e)->app_data)
+#define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d))
+#define EVP_CIPHER_CTX_type(c)         EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c))
+#define EVP_CIPHER_CTX_flags(e)		((e)->cipher->flags)
+#define EVP_CIPHER_CTX_mode(e)		((e)->cipher->flags & EVP_CIPH_MODE)
+
+#define EVP_ENCODE_LENGTH(l)	(((l+2)/3*4)+(l/48+1)*2+80)
+#define EVP_DECODE_LENGTH(l)	((l+3)/4*3+80)
+
+#define EVP_SignInit_ex(a,b,c)		EVP_DigestInit_ex(a,b,c)
+#define EVP_SignInit(a,b)		EVP_DigestInit(a,b)
+#define EVP_SignUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+#define	EVP_VerifyInit_ex(a,b,c)	EVP_DigestInit_ex(a,b,c)
+#define	EVP_VerifyInit(a,b)		EVP_DigestInit(a,b)
+#define	EVP_VerifyUpdate(a,b,c)		EVP_DigestUpdate(a,b,c)
+#define EVP_OpenUpdate(a,b,c,d,e)	EVP_DecryptUpdate(a,b,c,d,e)
+#define EVP_SealUpdate(a,b,c,d,e)	EVP_EncryptUpdate(a,b,c,d,e)	
+
+#ifdef CONST_STRICT
+void BIO_set_md(BIO *,const EVP_MD *md);
+#else
+# define BIO_set_md(b,md)		BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md)
+#endif
+#define BIO_get_md(b,mdp)		BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp)
+#define BIO_get_md_ctx(b,mdcp)     BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp)
+#define BIO_get_cipher_status(b)	BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL)
+#define BIO_get_cipher_ctx(b,c_pp)	BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp)
+
+#define	EVP_Cipher(c,o,i,l)	(c)->cipher->do_cipher((c),(o),(i),(l))
+
+#define EVP_add_cipher_alias(n,alias) \
+	OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_add_digest_alias(n,alias) \
+	OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n))
+#define EVP_delete_cipher_alias(alias) \
+	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS);
+#define EVP_delete_digest_alias(alias) \
+	OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS);
+
+void	EVP_MD_CTX_init(EVP_MD_CTX *ctx);
+int	EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
+EVP_MD_CTX *EVP_MD_CTX_create(void);
+void	EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);
+int     EVP_MD_CTX_copy_ex(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
+#define EVP_MD_CTX_set_flags(ctx,flgs) ((ctx)->flags|=(flgs))
+#define EVP_MD_CTX_clear_flags(ctx,flgs) ((ctx)->flags&=~(flgs))
+#define EVP_MD_CTX_test_flags(ctx,flgs) ((ctx)->flags&(flgs))
+int	EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
+int	EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d,
+			 size_t cnt);
+int	EVP_DigestFinal_ex(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
+int	EVP_Digest(const void *data, size_t count,
+		unsigned char *md, unsigned int *size, const EVP_MD *type, ENGINE *impl);
+
+int     EVP_MD_CTX_copy(EVP_MD_CTX *out,const EVP_MD_CTX *in);  
+int	EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type);
+int	EVP_DigestFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s);
+
+int	EVP_read_pw_string(char *buf,int length,const char *prompt,int verify);
+void	EVP_set_pw_prompt(const char *prompt);
+char *	EVP_get_pw_prompt(void);
+
+int	EVP_BytesToKey(const EVP_CIPHER *type,const EVP_MD *md,
+		const unsigned char *salt, const unsigned char *data,
+		int datal, int count, unsigned char *key,unsigned char *iv);
+
+int	EVP_EncryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, const unsigned char *in, int inl);
+int	EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+int	EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int	EVP_DecryptInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		const unsigned char *key, const unsigned char *iv);
+int	EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, const unsigned char *in, int inl);
+int	EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int	EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int	EVP_CipherInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher,
+		       const unsigned char *key,const unsigned char *iv,
+		       int enc);
+int	EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl,
+		       const unsigned char *key,const unsigned char *iv,
+		       int enc);
+int	EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
+		int *outl, const unsigned char *in, int inl);
+int	EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+int	EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);
+
+int	EVP_SignFinal(EVP_MD_CTX *ctx,unsigned char *md,unsigned int *s,
+		EVP_PKEY *pkey);
+
+int	EVP_VerifyFinal(EVP_MD_CTX *ctx,const unsigned char *sigbuf,
+		unsigned int siglen,EVP_PKEY *pkey);
+
+int	EVP_OpenInit(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *type,
+		const unsigned char *ek, int ekl, const unsigned char *iv,
+		EVP_PKEY *priv);
+int	EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl);
+
+int	EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type,
+		 unsigned char **ek, int *ekl, unsigned char *iv,
+		EVP_PKEY **pubk, int npubk);
+int	EVP_SealFinal(EVP_CIPHER_CTX *ctx,unsigned char *out,int *outl);
+
+void	EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
+void	EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
+		const unsigned char *in,int inl);
+void	EVP_EncodeFinal(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl);
+int	EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void	EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
+int	EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx,unsigned char *out,int *outl,
+		const unsigned char *in, int inl);
+int	EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned
+		char *out, int *outl);
+int	EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n);
+
+void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
+int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
+int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
+int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
+int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key);
+
+#ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_md(void);
+BIO_METHOD *BIO_f_base64(void);
+BIO_METHOD *BIO_f_cipher(void);
+BIO_METHOD *BIO_f_reliable(void);
+void BIO_set_cipher(BIO *b,const EVP_CIPHER *c,const unsigned char *k,
+		const unsigned char *i, int enc);
+#endif
+
+const EVP_MD *EVP_md_null(void);
+#ifndef OPENSSL_NO_MD2
+const EVP_MD *EVP_md2(void);
+#endif
+#ifndef OPENSSL_NO_MD4
+const EVP_MD *EVP_md4(void);
+#endif
+#ifndef OPENSSL_NO_MD5
+const EVP_MD *EVP_md5(void);
+#endif
+#ifndef OPENSSL_NO_SHA
+const EVP_MD *EVP_sha(void);
+const EVP_MD *EVP_sha1(void);
+const EVP_MD *EVP_dss(void);
+const EVP_MD *EVP_dss1(void);
+const EVP_MD *EVP_ecdsa(void);
+#endif
+#ifndef OPENSSL_NO_SHA256
+const EVP_MD *EVP_sha224(void);
+const EVP_MD *EVP_sha256(void);
+#endif
+#ifndef OPENSSL_NO_SHA512
+const EVP_MD *EVP_sha384(void);
+const EVP_MD *EVP_sha512(void);
+#endif
+#ifndef OPENSSL_NO_MDC2
+const EVP_MD *EVP_mdc2(void);
+#endif
+#ifndef OPENSSL_NO_RIPEMD
+const EVP_MD *EVP_ripemd160(void);
+#endif
+const EVP_CIPHER *EVP_enc_null(void);		/* does nothing :-) */
+#ifndef OPENSSL_NO_DES
+const EVP_CIPHER *EVP_des_ecb(void);
+const EVP_CIPHER *EVP_des_ede(void);
+const EVP_CIPHER *EVP_des_ede3(void);
+const EVP_CIPHER *EVP_des_ede_ecb(void);
+const EVP_CIPHER *EVP_des_ede3_ecb(void);
+const EVP_CIPHER *EVP_des_cfb64(void);
+# define EVP_des_cfb EVP_des_cfb64
+const EVP_CIPHER *EVP_des_cfb1(void);
+const EVP_CIPHER *EVP_des_cfb8(void);
+const EVP_CIPHER *EVP_des_ede_cfb64(void);
+# define EVP_des_ede_cfb EVP_des_ede_cfb64
+#if 0
+const EVP_CIPHER *EVP_des_ede_cfb1(void);
+const EVP_CIPHER *EVP_des_ede_cfb8(void);
+#endif
+const EVP_CIPHER *EVP_des_ede3_cfb64(void);
+# define EVP_des_ede3_cfb EVP_des_ede3_cfb64
+const EVP_CIPHER *EVP_des_ede3_cfb1(void);
+const EVP_CIPHER *EVP_des_ede3_cfb8(void);
+const EVP_CIPHER *EVP_des_ofb(void);
+const EVP_CIPHER *EVP_des_ede_ofb(void);
+const EVP_CIPHER *EVP_des_ede3_ofb(void);
+const EVP_CIPHER *EVP_des_cbc(void);
+const EVP_CIPHER *EVP_des_ede_cbc(void);
+const EVP_CIPHER *EVP_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_desx_cbc(void);
+/* This should now be supported through the dev_crypto ENGINE. But also, why are
+ * rc4 and md5 declarations made here inside a "NO_DES" precompiler branch? */
+#if 0
+# ifdef OPENSSL_OPENBSD_DEV_CRYPTO
+const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void);
+const EVP_CIPHER *EVP_dev_crypto_rc4(void);
+const EVP_MD *EVP_dev_crypto_md5(void);
+# endif
+#endif
+#endif
+#ifndef OPENSSL_NO_RC4
+const EVP_CIPHER *EVP_rc4(void);
+const EVP_CIPHER *EVP_rc4_40(void);
+#endif
+#ifndef OPENSSL_NO_IDEA
+const EVP_CIPHER *EVP_idea_ecb(void);
+const EVP_CIPHER *EVP_idea_cfb64(void);
+# define EVP_idea_cfb EVP_idea_cfb64
+const EVP_CIPHER *EVP_idea_ofb(void);
+const EVP_CIPHER *EVP_idea_cbc(void);
+#endif
+#ifndef OPENSSL_NO_RC2
+const EVP_CIPHER *EVP_rc2_ecb(void);
+const EVP_CIPHER *EVP_rc2_cbc(void);
+const EVP_CIPHER *EVP_rc2_40_cbc(void);
+const EVP_CIPHER *EVP_rc2_64_cbc(void);
+const EVP_CIPHER *EVP_rc2_cfb64(void);
+# define EVP_rc2_cfb EVP_rc2_cfb64
+const EVP_CIPHER *EVP_rc2_ofb(void);
+#endif
+#ifndef OPENSSL_NO_BF
+const EVP_CIPHER *EVP_bf_ecb(void);
+const EVP_CIPHER *EVP_bf_cbc(void);
+const EVP_CIPHER *EVP_bf_cfb64(void);
+# define EVP_bf_cfb EVP_bf_cfb64
+const EVP_CIPHER *EVP_bf_ofb(void);
+#endif
+#ifndef OPENSSL_NO_CAST
+const EVP_CIPHER *EVP_cast5_ecb(void);
+const EVP_CIPHER *EVP_cast5_cbc(void);
+const EVP_CIPHER *EVP_cast5_cfb64(void);
+# define EVP_cast5_cfb EVP_cast5_cfb64
+const EVP_CIPHER *EVP_cast5_ofb(void);
+#endif
+#ifndef OPENSSL_NO_RC5
+const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void);
+const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void);
+# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64
+const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void);
+#endif
+#ifndef OPENSSL_NO_AES
+const EVP_CIPHER *EVP_aes_128_ecb(void);
+const EVP_CIPHER *EVP_aes_128_cbc(void);
+const EVP_CIPHER *EVP_aes_128_cfb1(void);
+const EVP_CIPHER *EVP_aes_128_cfb8(void);
+const EVP_CIPHER *EVP_aes_128_cfb128(void);
+# define EVP_aes_128_cfb EVP_aes_128_cfb128
+const EVP_CIPHER *EVP_aes_128_ofb(void);
+#if 0
+const EVP_CIPHER *EVP_aes_128_ctr(void);
+#endif
+const EVP_CIPHER *EVP_aes_192_ecb(void);
+const EVP_CIPHER *EVP_aes_192_cbc(void);
+const EVP_CIPHER *EVP_aes_192_cfb1(void);
+const EVP_CIPHER *EVP_aes_192_cfb8(void);
+const EVP_CIPHER *EVP_aes_192_cfb128(void);
+# define EVP_aes_192_cfb EVP_aes_192_cfb128
+const EVP_CIPHER *EVP_aes_192_ofb(void);
+#if 0
+const EVP_CIPHER *EVP_aes_192_ctr(void);
+#endif
+const EVP_CIPHER *EVP_aes_256_ecb(void);
+const EVP_CIPHER *EVP_aes_256_cbc(void);
+const EVP_CIPHER *EVP_aes_256_cfb1(void);
+const EVP_CIPHER *EVP_aes_256_cfb8(void);
+const EVP_CIPHER *EVP_aes_256_cfb128(void);
+# define EVP_aes_256_cfb EVP_aes_256_cfb128
+const EVP_CIPHER *EVP_aes_256_ofb(void);
+#if 0
+const EVP_CIPHER *EVP_aes_256_ctr(void);
+#endif
+#endif
+
+void OPENSSL_add_all_algorithms_noconf(void);
+void OPENSSL_add_all_algorithms_conf(void);
+
+#ifdef OPENSSL_LOAD_CONF
+#define OpenSSL_add_all_algorithms() \
+		OPENSSL_add_all_algorithms_conf()
+#else
+#define OpenSSL_add_all_algorithms() \
+		OPENSSL_add_all_algorithms_noconf()
+#endif
+
+void OpenSSL_add_all_ciphers(void);
+void OpenSSL_add_all_digests(void);
+#define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms()
+#define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers()
+#define SSLeay_add_all_digests() OpenSSL_add_all_digests()
+
+int EVP_add_cipher(const EVP_CIPHER *cipher);
+int EVP_add_digest(const EVP_MD *digest);
+
+const EVP_CIPHER *EVP_get_cipherbyname(const char *name);
+const EVP_MD *EVP_get_digestbyname(const char *name);
+void EVP_cleanup(void);
+
+int		EVP_PKEY_decrypt(unsigned char *dec_key,
+			const unsigned char *enc_key,int enc_key_len,
+			EVP_PKEY *private_key);
+int		EVP_PKEY_encrypt(unsigned char *enc_key,
+			const unsigned char *key,int key_len,
+			EVP_PKEY *pub_key);
+int		EVP_PKEY_type(int type);
+int		EVP_PKEY_bits(EVP_PKEY *pkey);
+int		EVP_PKEY_size(EVP_PKEY *pkey);
+int 		EVP_PKEY_assign(EVP_PKEY *pkey,int type,char *key);
+
+#ifndef OPENSSL_NO_RSA
+struct rsa_st;
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey,struct rsa_st *key);
+struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey);
+#endif
+#ifndef OPENSSL_NO_DSA
+struct dsa_st;
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey,struct dsa_st *key);
+struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey);
+#endif
+#ifndef OPENSSL_NO_DH
+struct dh_st;
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey,struct dh_st *key);
+struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
+#endif
+#ifndef OPENSSL_NO_EC
+struct ec_key_st;
+int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey,struct ec_key_st *key);
+struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey);
+#endif
+
+EVP_PKEY *	EVP_PKEY_new(void);
+void		EVP_PKEY_free(EVP_PKEY *pkey);
+
+EVP_PKEY *	d2i_PublicKey(int type,EVP_PKEY **a, const unsigned char **pp,
+			long length);
+int		i2d_PublicKey(EVP_PKEY *a, unsigned char **pp);
+
+EVP_PKEY *	d2i_PrivateKey(int type,EVP_PKEY **a, const unsigned char **pp,
+			long length);
+EVP_PKEY *	d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+			long length);
+int		i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
+
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from);
+int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey);
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode);
+int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b);
+
+int EVP_CIPHER_type(const EVP_CIPHER *ctx);
+
+/* calls methods */
+int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
+
+/* These are used by EVP_CIPHER methods */
+int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
+int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c,ASN1_TYPE *type);
+
+/* PKCS5 password based encryption */
+int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
+			 int en_de);
+int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
+			   const unsigned char *salt, int saltlen, int iter,
+			   int keylen, unsigned char *out);
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md,
+			 int en_de);
+
+void PKCS5_PBE_add(void);
+
+int EVP_PBE_CipherInit (ASN1_OBJECT *pbe_obj, const char *pass, int passlen,
+	     ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de);
+int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md,
+		    EVP_PBE_KEYGEN *keygen);
+void EVP_PBE_cleanup(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_EVP_strings(void);
+
+/* Error codes for the EVP functions. */
+
+/* Function codes. */
+#define EVP_F_AES_INIT_KEY				 133
+#define EVP_F_D2I_PKEY					 100
+#define EVP_F_DSAPKEY2PKCS8				 134
+#define EVP_F_DSA_PKEY2PKCS8				 135
+#define EVP_F_ECDSA_PKEY2PKCS8				 129
+#define EVP_F_ECKEY_PKEY2PKCS8				 132
+#define EVP_F_EVP_CIPHERINIT_EX				 123
+#define EVP_F_EVP_CIPHER_CTX_CTRL			 124
+#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH		 122
+#define EVP_F_EVP_DECRYPTFINAL_EX			 101
+#define EVP_F_EVP_DIGESTINIT_EX				 128
+#define EVP_F_EVP_ENCRYPTFINAL_EX			 127
+#define EVP_F_EVP_MD_CTX_COPY_EX			 110
+#define EVP_F_EVP_OPENINIT				 102
+#define EVP_F_EVP_PBE_ALG_ADD				 115
+#define EVP_F_EVP_PBE_CIPHERINIT			 116
+#define EVP_F_EVP_PKCS82PKEY				 111
+#define EVP_F_EVP_PKEY2PKCS8_BROKEN			 113
+#define EVP_F_EVP_PKEY_COPY_PARAMETERS			 103
+#define EVP_F_EVP_PKEY_DECRYPT				 104
+#define EVP_F_EVP_PKEY_ENCRYPT				 105
+#define EVP_F_EVP_PKEY_GET1_DH				 119
+#define EVP_F_EVP_PKEY_GET1_DSA				 120
+#define EVP_F_EVP_PKEY_GET1_ECDSA			 130
+#define EVP_F_EVP_PKEY_GET1_EC_KEY			 131
+#define EVP_F_EVP_PKEY_GET1_RSA				 121
+#define EVP_F_EVP_PKEY_NEW				 106
+#define EVP_F_EVP_RIJNDAEL				 126
+#define EVP_F_EVP_SIGNFINAL				 107
+#define EVP_F_EVP_VERIFYFINAL				 108
+#define EVP_F_PKCS5_PBE_KEYIVGEN			 117
+#define EVP_F_PKCS5_V2_PBE_KEYIVGEN			 118
+#define EVP_F_PKCS8_SET_BROKEN				 112
+#define EVP_F_RC2_MAGIC_TO_METH				 109
+#define EVP_F_RC5_CTRL					 125
+
+/* Reason codes. */
+#define EVP_R_AES_KEY_SETUP_FAILED			 143
+#define EVP_R_ASN1_LIB					 140
+#define EVP_R_BAD_BLOCK_LENGTH				 136
+#define EVP_R_BAD_DECRYPT				 100
+#define EVP_R_BAD_KEY_LENGTH				 137
+#define EVP_R_BN_DECODE_ERROR				 112
+#define EVP_R_BN_PUBKEY_ERROR				 113
+#define EVP_R_CIPHER_PARAMETER_ERROR			 122
+#define EVP_R_CTRL_NOT_IMPLEMENTED			 132
+#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED		 133
+#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH		 138
+#define EVP_R_DECODE_ERROR				 114
+#define EVP_R_DIFFERENT_KEY_TYPES			 101
+#define EVP_R_ENCODE_ERROR				 115
+#define EVP_R_EVP_PBE_CIPHERINIT_ERROR			 119
+#define EVP_R_EXPECTING_AN_RSA_KEY			 127
+#define EVP_R_EXPECTING_A_DH_KEY			 128
+#define EVP_R_EXPECTING_A_DSA_KEY			 129
+#define EVP_R_EXPECTING_A_ECDSA_KEY			 141
+#define EVP_R_EXPECTING_A_EC_KEY			 142
+#define EVP_R_INITIALIZATION_ERROR			 134
+#define EVP_R_INPUT_NOT_INITIALIZED			 111
+#define EVP_R_INVALID_KEY_LENGTH			 130
+#define EVP_R_IV_TOO_LARGE				 102
+#define EVP_R_KEYGEN_FAILURE				 120
+#define EVP_R_MISSING_PARAMETERS			 103
+#define EVP_R_NO_CIPHER_SET				 131
+#define EVP_R_NO_DIGEST_SET				 139
+#define EVP_R_NO_DSA_PARAMETERS				 116
+#define EVP_R_NO_SIGN_FUNCTION_CONFIGURED		 104
+#define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
+#define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE			 117
+#define EVP_R_PUBLIC_KEY_NOT_RSA			 106
+#define EVP_R_UNKNOWN_PBE_ALGORITHM			 121
+#define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS		 135
+#define EVP_R_UNSUPPORTED_CIPHER			 107
+#define EVP_R_UNSUPPORTED_KEYLENGTH			 123
+#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION	 124
+#define EVP_R_UNSUPPORTED_KEY_SIZE			 108
+#define EVP_R_UNSUPPORTED_PRF				 125
+#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM		 118
+#define EVP_R_UNSUPPORTED_SALT_TYPE			 126
+#define EVP_R_WRONG_FINAL_BLOCK_LENGTH			 109
+#define EVP_R_WRONG_PUBLIC_KEY_TYPE			 110
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/fips.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/fips.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/fips.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,126 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_FIPS
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Note that these are defined in crypto/cryptlib.c so they're
+ * available even without -lfips.
+ */
+struct dsa_st;
+
+int FIPS_mode_set(int onoff,const char *path);
+void FIPS_allow_md5(int onoff);
+int FIPS_md5_allowed(void);
+int FIPS_selftest_failed(void);
+int FIPS_dsa_check(struct dsa_st *dsa);
+void FIPS_corrupt_sha1(void);
+int FIPS_selftest_sha1(void);
+void FIPS_corrupt_aes(void);
+int FIPS_selftest_aes(void);
+void FIPS_corrupt_des(void);
+int FIPS_selftest_des(void);
+void FIPS_corrupt_rsa(void);
+int FIPS_selftest_rsa(void);
+void FIPS_corrupt_dsa(void);
+int FIPS_selftest_dsa(void);
+
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_FIPS_strings(void);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_FIPS_strings(void);
+
+/* Error codes for the FIPS functions. */
+
+/* Function codes. */
+#define FIPS_F_DSA_DO_SIGN				 111
+#define FIPS_F_DSA_DO_VERIFY				 112
+#define FIPS_F_DSA_GENERATE_PARAMETERS			 110
+#define FIPS_F_FIPS_CHECK_DSA				 116
+#define FIPS_F_FIPS_CHECK_EXE				 106
+#define FIPS_F_FIPS_CHECK_RSA				 115
+#define FIPS_F_FIPS_DSA_CHECK				 102
+#define FIPS_F_FIPS_MODE_SET				 105
+#define FIPS_F_FIPS_SELFTEST_AES			 104
+#define FIPS_F_FIPS_SELFTEST_DES			 107
+#define FIPS_F_FIPS_SELFTEST_DSA			 109
+#define FIPS_F_FIPS_SELFTEST_RSA			 108
+#define FIPS_F_FIPS_SELFTEST_SHA1			 103
+#define FIPS_F_HASH_FINAL				 100
+#define FIPS_F_DH_GENERATE_PARAMETERS			 117
+#define FIPS_F_RSA_EAY_PUBLIC_ENCRYPT			 114
+#define FIPS_F_RSA_GENERATE_KEY				 113
+#define FIPS_F_SSLEAY_RAND_BYTES			 101
+
+/* Reason codes. */
+#define FIPS_R_CANNOT_READ_EXE				 103
+#define FIPS_R_CANNOT_READ_EXE_DIGEST			 104
+#define FIPS_R_EXE_DIGEST_DOES_NOT_MATCH		 105
+#define FIPS_R_FIPS_MODE_ALREADY_SET			 102
+#define FIPS_R_FIPS_SELFTEST_FAILED			 106
+#define FIPS_R_NON_FIPS_METHOD				 100
+#define FIPS_R_PAIRWISE_TEST_FAILED			 107
+#define FIPS_R_SELFTEST_FAILED				 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/fips_rand.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/fips_rand.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/fips_rand.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,74 @@
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef HEADER_FIPS_RAND_H
+#define HEADER_FIPS_RAND_H
+
+#include "des.h"
+
+#ifdef OPENSSL_FIPS
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+void FIPS_set_prng_key(const unsigned char k1[8],const unsigned char k2[8]);
+void FIPS_test_mode(int test,const unsigned char faketime[8]);
+void FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num);
+/* NB: this returns true if _partially_ seeded */
+int FIPS_rand_seeded(void);
+
+RAND_METHOD *FIPS_rand_method(void);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/hmac.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/hmac.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/hmac.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,108 @@
+/* crypto/hmac/hmac.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+#ifndef HEADER_HMAC_H
+#define HEADER_HMAC_H
+
+#include <openssl/opensslconf.h>
+
+#ifdef OPENSSL_NO_HMAC
+#error HMAC is disabled.
+#endif
+
+#include <openssl/evp.h>
+
+#define HMAC_MAX_MD_CBLOCK	128	/* largest known is SHA512 */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct hmac_ctx_st
+	{
+	const EVP_MD *md;
+	EVP_MD_CTX md_ctx;
+	EVP_MD_CTX i_ctx;
+	EVP_MD_CTX o_ctx;
+	unsigned int key_length;
+	unsigned char key[HMAC_MAX_MD_CBLOCK];
+	} HMAC_CTX;
+
+#define HMAC_size(e)	(EVP_MD_size((e)->md))
+
+
+void HMAC_CTX_init(HMAC_CTX *ctx);
+void HMAC_CTX_cleanup(HMAC_CTX *ctx);
+
+#define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) /* deprecated */
+
+void HMAC_Init(HMAC_CTX *ctx, const void *key, int len,
+	       const EVP_MD *md); /* deprecated */
+void HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len,
+		  const EVP_MD *md, ENGINE *impl);
+void HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len);
+void HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len);
+unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
+		    const unsigned char *d, size_t n, unsigned char *md,
+		    unsigned int *md_len);
+
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/idea.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/idea.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/idea.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,100 @@
+/* crypto/idea/idea.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_IDEA_H
+#define HEADER_IDEA_H
+
+#include <openssl/opensslconf.h> /* IDEA_INT, OPENSSL_NO_IDEA */
+
+#ifdef OPENSSL_NO_IDEA
+#error IDEA is disabled.
+#endif
+
+#define IDEA_ENCRYPT	1
+#define IDEA_DECRYPT	0
+
+#define IDEA_BLOCK	8
+#define IDEA_KEY_LENGTH	16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct idea_key_st
+	{
+	IDEA_INT data[9][6];
+	} IDEA_KEY_SCHEDULE;
+
+const char *idea_options(void);
+void idea_ecb_encrypt(const unsigned char *in, unsigned char *out,
+	IDEA_KEY_SCHEDULE *ks);
+void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks);
+void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk);
+void idea_cbc_encrypt(const unsigned char *in, unsigned char *out,
+	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,int enc);
+void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv,
+	int *num,int enc);
+void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+	long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, int *num);
+void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/krb5_asn.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/krb5_asn.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/krb5_asn.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,256 @@
+/* krb5_asn.h */
+/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project,
+** using ocsp/{*.h,*asn*.c} as a starting point
+*/
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_KRB5_ASN_H
+#define HEADER_KRB5_ASN_H
+
+/*
+#include <krb5.h>
+*/
+#include <openssl/safestack.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+
+/*	ASN.1 from Kerberos RFC 1510
+*/
+
+/*	EncryptedData ::=   SEQUENCE {
+**		etype[0]                      INTEGER, -- EncryptionType
+**		kvno[1]                       INTEGER OPTIONAL,
+**		cipher[2]                     OCTET STRING -- ciphertext
+**	}
+*/
+typedef	struct	krb5_encdata_st
+	{
+	ASN1_INTEGER			*etype;
+	ASN1_INTEGER			*kvno;
+	ASN1_OCTET_STRING		*cipher;
+	}	KRB5_ENCDATA;
+
+DECLARE_STACK_OF(KRB5_ENCDATA)
+
+/*	PrincipalName ::=   SEQUENCE {
+**		name-type[0]                  INTEGER,
+**		name-string[1]                SEQUENCE OF GeneralString
+**	}
+*/
+typedef	struct	krb5_princname_st
+	{
+	ASN1_INTEGER			*nametype;
+	STACK_OF(ASN1_GENERALSTRING)	*namestring;
+	}	KRB5_PRINCNAME;
+
+DECLARE_STACK_OF(KRB5_PRINCNAME)
+
+
+/*	Ticket ::=	[APPLICATION 1] SEQUENCE {
+**		tkt-vno[0]                    INTEGER,
+**		realm[1]                      Realm,
+**		sname[2]                      PrincipalName,
+**		enc-part[3]                   EncryptedData
+**	}
+*/
+typedef	struct	krb5_tktbody_st
+	{
+	ASN1_INTEGER			*tktvno;
+	ASN1_GENERALSTRING		*realm;
+	KRB5_PRINCNAME			*sname;
+	KRB5_ENCDATA			*encdata;
+	}	KRB5_TKTBODY;
+
+typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET;
+DECLARE_STACK_OF(KRB5_TKTBODY)
+
+
+/*	AP-REQ ::=      [APPLICATION 14] SEQUENCE {
+**		pvno[0]                       INTEGER,
+**		msg-type[1]                   INTEGER,
+**		ap-options[2]                 APOptions,
+**		ticket[3]                     Ticket,
+**		authenticator[4]              EncryptedData
+**	}
+**
+**	APOptions ::=   BIT STRING {
+**		reserved(0), use-session-key(1), mutual-required(2) }
+*/
+typedef	struct	krb5_ap_req_st
+	{
+	ASN1_INTEGER			*pvno;
+	ASN1_INTEGER			*msgtype;
+	ASN1_BIT_STRING			*apoptions;
+	KRB5_TICKET			*ticket;
+	KRB5_ENCDATA			*authenticator;
+	}	KRB5_APREQBODY;
+
+typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ;
+DECLARE_STACK_OF(KRB5_APREQBODY)
+
+
+/*	Authenticator Stuff	*/
+
+
+/*	Checksum ::=   SEQUENCE {
+**		cksumtype[0]                  INTEGER,
+**		checksum[1]                   OCTET STRING
+**	}
+*/
+typedef	struct	krb5_checksum_st
+	{
+	ASN1_INTEGER			*ctype;
+	ASN1_OCTET_STRING		*checksum;
+	}	KRB5_CHECKSUM;
+
+DECLARE_STACK_OF(KRB5_CHECKSUM)
+
+
+/*	EncryptionKey ::=   SEQUENCE {
+**		keytype[0]                    INTEGER,
+**		keyvalue[1]                   OCTET STRING
+**	}
+*/
+typedef struct  krb5_encryptionkey_st
+	{
+	ASN1_INTEGER			*ktype;
+	ASN1_OCTET_STRING		*keyvalue;
+	}	KRB5_ENCKEY;
+
+DECLARE_STACK_OF(KRB5_ENCKEY)
+
+
+/*	AuthorizationData ::=   SEQUENCE OF SEQUENCE {
+**		ad-type[0]                    INTEGER,
+**              ad-data[1]                    OCTET STRING
+**	}
+*/
+typedef struct	krb5_authorization_st
+	{
+	ASN1_INTEGER			*adtype;
+	ASN1_OCTET_STRING		*addata;
+	}	KRB5_AUTHDATA;
+
+DECLARE_STACK_OF(KRB5_AUTHDATA)
+
+			
+/*	-- Unencrypted authenticator
+**	Authenticator ::=    [APPLICATION 2] SEQUENCE    {
+**		authenticator-vno[0]          INTEGER,
+**		crealm[1]                     Realm,
+**		cname[2]                      PrincipalName,
+**		cksum[3]                      Checksum OPTIONAL,
+**		cusec[4]                      INTEGER,
+**		ctime[5]                      KerberosTime,
+**		subkey[6]                     EncryptionKey OPTIONAL,
+**		seq-number[7]                 INTEGER OPTIONAL,
+**		authorization-data[8]         AuthorizationData OPTIONAL
+**	}
+*/
+typedef struct	krb5_authenticator_st
+	{
+	ASN1_INTEGER			*avno;
+	ASN1_GENERALSTRING		*crealm;
+	KRB5_PRINCNAME			*cname;
+	KRB5_CHECKSUM			*cksum;
+	ASN1_INTEGER			*cusec;
+	ASN1_GENERALIZEDTIME		*ctime;
+	KRB5_ENCKEY			*subkey;
+	ASN1_INTEGER			*seqnum;
+	KRB5_AUTHDATA			*authorization;
+	}	KRB5_AUTHENTBODY;
+
+typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT;
+DECLARE_STACK_OF(KRB5_AUTHENTBODY)
+
+
+/*  DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) =
+**	type *name##_new(void);
+**	void name##_free(type *a);
+**	DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) =
+**	 DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) =
+**	  type *d2i_##name(type **a, const unsigned char **in, long len);
+**	  int i2d_##name(type *a, unsigned char **out);
+**	  DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it
+*/
+
+DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA)
+DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME)
+DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_TICKET)
+DECLARE_ASN1_FUNCTIONS(KRB5_APREQ)
+
+DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM)
+DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY)
+DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT)
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/kssl.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/kssl.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/kssl.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,179 @@
+/* ssl/kssl.h -*- mode: C; c-file-style: "eay" -*- */
+/* Written by Vern Staats <staatsvr@asc.hpc.mil> for the OpenSSL project 2000.
+ * project 2000.
+ */
+/* ====================================================================
+ * Copyright (c) 2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+**	19990701	VRS 	Started.
+*/
+
+#ifndef	KSSL_H
+#define	KSSL_H
+
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_NO_KRB5
+
+#include <stdio.h>
+#include <ctype.h>
+#include <krb5.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+**	Depending on which KRB5 implementation used, some types from
+**	the other may be missing.  Resolve that here and now
+*/
+#ifdef KRB5_HEIMDAL
+typedef unsigned char krb5_octet;
+#define FAR
+#else
+
+#ifndef FAR
+#define FAR
+#endif
+
+#endif
+
+/*	Uncomment this to debug kssl problems or
+**	to trace usage of the Kerberos session key
+**
+**	#define		KSSL_DEBUG
+*/
+
+#ifndef	KRB5SVC
+#define KRB5SVC	"host"
+#endif
+
+#ifndef	KRB5KEYTAB
+#define KRB5KEYTAB	"/etc/krb5.keytab"
+#endif
+
+#ifndef KRB5SENDAUTH
+#define KRB5SENDAUTH	1
+#endif
+
+#ifndef KRB5CHECKAUTH
+#define KRB5CHECKAUTH	1
+#endif
+
+#ifndef KSSL_CLOCKSKEW
+#define	KSSL_CLOCKSKEW	300;
+#endif
+
+#define	KSSL_ERR_MAX	255
+typedef struct kssl_err_st  {
+	int  reason;
+	char text[KSSL_ERR_MAX+1];
+	} KSSL_ERR;
+
+
+/*	Context for passing
+**		(1) Kerberos session key to SSL, and
+**		(2)	Config data between application and SSL lib
+*/
+typedef struct kssl_ctx_st
+        {
+                                /*	used by:    disposition:            */
+	char *service_name;	/*	C,S	    default ok (kssl)       */
+	char *service_host;	/*	C	    input, REQUIRED         */
+	char *client_princ;	/*	S	    output from krb5 ticket */
+	char *keytab_file;	/*      S	    NULL (/etc/krb5.keytab) */
+	char *cred_cache;	/*	C	    NULL (default)          */
+	krb5_enctype enctype;
+	int length;
+	krb5_octet FAR *key;
+	} KSSL_CTX;
+
+#define	KSSL_CLIENT 	1
+#define KSSL_SERVER 	2
+#define	KSSL_SERVICE	3
+#define	KSSL_KEYTAB 	4
+
+#define KSSL_CTX_OK 	0
+#define KSSL_CTX_ERR	1
+#define KSSL_NOMEM	2
+
+/* Public (for use by applications that use OpenSSL with Kerberos 5 support */
+krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text);
+KSSL_CTX *kssl_ctx_new(void);
+KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx);
+void kssl_ctx_show(KSSL_CTX *kssl_ctx);
+krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which,
+        krb5_data *realm, krb5_data *entity, int nentities);
+krb5_error_code	kssl_cget_tkt(KSSL_CTX *kssl_ctx,  krb5_data **enc_tktp,
+        krb5_data *authenp, KSSL_ERR *kssl_err);
+krb5_error_code	kssl_sget_tkt(KSSL_CTX *kssl_ctx,  krb5_data *indata,
+        krb5_ticket_times *ttimes, KSSL_ERR *kssl_err);
+krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session);
+void	kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text);
+void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data);
+krb5_error_code  kssl_build_principal_2(krb5_context context,
+			krb5_principal *princ, int rlen, const char *realm,
+			int slen, const char *svc, int hlen, const char *host);
+krb5_error_code  kssl_validate_times(krb5_timestamp atime,
+					krb5_ticket_times *ttimes);
+krb5_error_code  kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp,
+			            krb5_timestamp *atimep, KSSL_ERR *kssl_err);
+unsigned char	*kssl_skip_confound(krb5_enctype enctype, unsigned char *authn);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif	/* OPENSSL_NO_KRB5	*/
+#endif	/* KSSL_H 	*/
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/lhash.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/lhash.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/lhash.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,200 @@
+/* crypto/lhash/lhash.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Header for dynamic hash table routines
+ * Author - Eric Young
+ */
+
+#ifndef HEADER_LHASH_H
+#define HEADER_LHASH_H
+
+#include <openssl/e_os2.h>
+#ifndef OPENSSL_NO_FP_API
+#include <stdio.h>
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct lhash_node_st
+	{
+	void *data;
+	struct lhash_node_st *next;
+#ifndef OPENSSL_NO_HASH_COMP
+	unsigned long hash;
+#endif
+	} LHASH_NODE;
+
+typedef int (*LHASH_COMP_FN_TYPE)(const void *, const void *);
+typedef unsigned long (*LHASH_HASH_FN_TYPE)(const void *);
+typedef void (*LHASH_DOALL_FN_TYPE)(void *);
+typedef void (*LHASH_DOALL_ARG_FN_TYPE)(void *, void *);
+
+/* Macros for declaring and implementing type-safe wrappers for LHASH callbacks.
+ * This way, callbacks can be provided to LHASH structures without function
+ * pointer casting and the macro-defined callbacks provide per-variable casting
+ * before deferring to the underlying type-specific callbacks. NB: It is
+ * possible to place a "static" in front of both the DECLARE and IMPLEMENT
+ * macros if the functions are strictly internal. */
+
+/* First: "hash" functions */
+#define DECLARE_LHASH_HASH_FN(f_name,o_type) \
+	unsigned long f_name##_LHASH_HASH(const void *);
+#define IMPLEMENT_LHASH_HASH_FN(f_name,o_type) \
+	unsigned long f_name##_LHASH_HASH(const void *arg) { \
+		o_type a = (o_type)arg; \
+		return f_name(a); }
+#define LHASH_HASH_FN(f_name) f_name##_LHASH_HASH
+
+/* Second: "compare" functions */
+#define DECLARE_LHASH_COMP_FN(f_name,o_type) \
+	int f_name##_LHASH_COMP(const void *, const void *);
+#define IMPLEMENT_LHASH_COMP_FN(f_name,o_type) \
+	int f_name##_LHASH_COMP(const void *arg1, const void *arg2) { \
+		o_type a = (o_type)arg1; \
+		o_type b = (o_type)arg2; \
+		return f_name(a,b); }
+#define LHASH_COMP_FN(f_name) f_name##_LHASH_COMP
+
+/* Third: "doall" functions */
+#define DECLARE_LHASH_DOALL_FN(f_name,o_type) \
+	void f_name##_LHASH_DOALL(void *);
+#define IMPLEMENT_LHASH_DOALL_FN(f_name,o_type) \
+	void f_name##_LHASH_DOALL(void *arg) { \
+		o_type a = (o_type)arg; \
+		f_name(a); }
+#define LHASH_DOALL_FN(f_name) f_name##_LHASH_DOALL
+
+/* Fourth: "doall_arg" functions */
+#define DECLARE_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \
+	void f_name##_LHASH_DOALL_ARG(void *, void *);
+#define IMPLEMENT_LHASH_DOALL_ARG_FN(f_name,o_type,a_type) \
+	void f_name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \
+		o_type a = (o_type)arg1; \
+		a_type b = (a_type)arg2; \
+		f_name(a,b); }
+#define LHASH_DOALL_ARG_FN(f_name) f_name##_LHASH_DOALL_ARG
+
+typedef struct lhash_st
+	{
+	LHASH_NODE **b;
+	LHASH_COMP_FN_TYPE comp;
+	LHASH_HASH_FN_TYPE hash;
+	unsigned int num_nodes;
+	unsigned int num_alloc_nodes;
+	unsigned int p;
+	unsigned int pmax;
+	unsigned long up_load; /* load times 256 */
+	unsigned long down_load; /* load times 256 */
+	unsigned long num_items;
+
+	unsigned long num_expands;
+	unsigned long num_expand_reallocs;
+	unsigned long num_contracts;
+	unsigned long num_contract_reallocs;
+	unsigned long num_hash_calls;
+	unsigned long num_comp_calls;
+	unsigned long num_insert;
+	unsigned long num_replace;
+	unsigned long num_delete;
+	unsigned long num_no_delete;
+	unsigned long num_retrieve;
+	unsigned long num_retrieve_miss;
+	unsigned long num_hash_comps;
+
+	int error;
+	} LHASH;
+
+#define LH_LOAD_MULT	256
+
+/* Indicates a malloc() error in the last call, this is only bad
+ * in lh_insert(). */
+#define lh_error(lh)	((lh)->error)
+
+LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c);
+void lh_free(LHASH *lh);
+void *lh_insert(LHASH *lh, void *data);
+void *lh_delete(LHASH *lh, const void *data);
+void *lh_retrieve(LHASH *lh, const void *data);
+void lh_doall(LHASH *lh, LHASH_DOALL_FN_TYPE func);
+void lh_doall_arg(LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg);
+unsigned long lh_strhash(const char *c);
+unsigned long lh_num_items(const LHASH *lh);
+
+#ifndef OPENSSL_NO_FP_API
+void lh_stats(const LHASH *lh, FILE *out);
+void lh_node_stats(const LHASH *lh, FILE *out);
+void lh_node_usage_stats(const LHASH *lh, FILE *out);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+void lh_stats_bio(const LHASH *lh, BIO *out);
+void lh_node_stats_bio(const LHASH *lh, BIO *out);
+void lh_node_usage_stats_bio(const LHASH *lh, BIO *out);
+#endif
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/md2.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/md2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/md2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,91 @@
+/* crypto/md/md2.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD2_H
+#define HEADER_MD2_H
+
+#include <openssl/opensslconf.h> /* OPENSSL_NO_MD2, MD2_INT */
+#ifdef OPENSSL_NO_MD2
+#error MD2 is disabled.
+#endif
+
+#define MD2_DIGEST_LENGTH	16
+#define MD2_BLOCK       	16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct MD2state_st
+	{
+	unsigned int num;
+	unsigned char data[MD2_BLOCK];
+	MD2_INT cksm[MD2_BLOCK];
+	MD2_INT state[MD2_BLOCK];
+	} MD2_CTX;
+
+const char *MD2_options(void);
+int MD2_Init(MD2_CTX *c);
+int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len);
+int MD2_Final(unsigned char *md, MD2_CTX *c);
+unsigned char *MD2(const unsigned char *d, size_t n,unsigned char *md);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/md4.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/md4.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/md4.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,116 @@
+/* crypto/md4/md4.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD4_H
+#define HEADER_MD4_H
+
+#include <openssl/e_os2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_MD4
+#error MD4 is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! MD4_LONG_LOG2 has to be defined along.			   !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define MD4_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define MD4_LONG unsigned long
+#define MD4_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *					<appro@fy.chalmers.se>
+ */
+#else
+#define MD4_LONG unsigned int
+#endif
+
+#define MD4_CBLOCK	64
+#define MD4_LBLOCK	(MD4_CBLOCK/4)
+#define MD4_DIGEST_LENGTH 16
+
+typedef struct MD4state_st
+	{
+	MD4_LONG A,B,C,D;
+	MD4_LONG Nl,Nh;
+	MD4_LONG data[MD4_LBLOCK];
+	unsigned int num;
+	} MD4_CTX;
+
+int MD4_Init(MD4_CTX *c);
+int MD4_Update(MD4_CTX *c, const void *data, size_t len);
+int MD4_Final(unsigned char *md, MD4_CTX *c);
+unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md);
+void MD4_Transform(MD4_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/md5.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/md5.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/md5.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,116 @@
+/* crypto/md5/md5.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MD5_H
+#define HEADER_MD5_H
+
+#include <openssl/e_os2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_MD5
+#error MD5 is disabled.
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! MD5_LONG_LOG2 has to be defined along.			   !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define MD5_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define MD5_LONG unsigned long
+#define MD5_LONG_LOG2 3
+/*
+ * _CRAY note. I could declare short, but I have no idea what impact
+ * does it have on performance on none-T3E machines. I could declare
+ * int, but at least on C90 sizeof(int) can be chosen at compile time.
+ * So I've chosen long...
+ *					<appro@fy.chalmers.se>
+ */
+#else
+#define MD5_LONG unsigned int
+#endif
+
+#define MD5_CBLOCK	64
+#define MD5_LBLOCK	(MD5_CBLOCK/4)
+#define MD5_DIGEST_LENGTH 16
+
+typedef struct MD5state_st
+	{
+	MD5_LONG A,B,C,D;
+	MD5_LONG Nl,Nh;
+	MD5_LONG data[MD5_LBLOCK];
+	unsigned int num;
+	} MD5_CTX;
+
+int MD5_Init(MD5_CTX *c);
+int MD5_Update(MD5_CTX *c, const void *data, size_t len);
+int MD5_Final(unsigned char *md, MD5_CTX *c);
+unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
+void MD5_Transform(MD5_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/mdc2.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/mdc2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/mdc2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,98 @@
+/* crypto/mdc2/mdc2.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_MDC2_H
+#define HEADER_MDC2_H
+
+#include <openssl/des.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_MDC2
+#error MDC2 is disabled.
+#endif
+
+#define MDC2_BLOCK              8
+#define MDC2_DIGEST_LENGTH      16
+ 
+typedef struct mdc2_ctx_st
+	{
+	int num;
+	unsigned char data[MDC2_BLOCK];
+	DES_cblock h,hh;
+	int pad_type; /* either 1 or 2, default 1 */
+	} MDC2_CTX;
+
+#ifdef OPENSSL_FIPS
+int private_MDC2_Init(MDC2_CTX *c);
+#endif
+int MDC2_Init(MDC2_CTX *c);
+int MDC2_Update(MDC2_CTX *c, const unsigned char *data, unsigned long len);
+int MDC2_Final(unsigned char *md, MDC2_CTX *c);
+unsigned char *MDC2(const unsigned char *d, unsigned long n,
+	unsigned char *md);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/obj_mac.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/obj_mac.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/obj_mac.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,3305 @@
+/* crypto/objects/obj_mac.h */
+
+/* THIS FILE IS GENERATED FROM objects.txt by objects.pl via the
+ * following command:
+ * perl objects.pl objects.txt obj_mac.num obj_mac.h
+ */
+
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#define SN_undef			"UNDEF"
+#define LN_undef			"undefined"
+#define NID_undef			0
+#define OBJ_undef			0L
+
+#define SN_itu_t		"ITU-T"
+#define LN_itu_t		"itu-t"
+#define NID_itu_t		645
+#define OBJ_itu_t		0L
+
+#define NID_ccitt		404
+#define OBJ_ccitt		OBJ_itu_t
+
+#define SN_iso		"ISO"
+#define LN_iso		"iso"
+#define NID_iso		181
+#define OBJ_iso		1L
+
+#define SN_joint_iso_itu_t		"JOINT-ISO-ITU-T"
+#define LN_joint_iso_itu_t		"joint-iso-itu-t"
+#define NID_joint_iso_itu_t		646
+#define OBJ_joint_iso_itu_t		2L
+
+#define NID_joint_iso_ccitt		393
+#define OBJ_joint_iso_ccitt		OBJ_joint_iso_itu_t
+
+#define SN_member_body		"member-body"
+#define LN_member_body		"ISO Member Body"
+#define NID_member_body		182
+#define OBJ_member_body		OBJ_iso,2L
+
+#define SN_identified_organization		"identified-organization"
+#define NID_identified_organization		676
+#define OBJ_identified_organization		OBJ_iso,3L
+
+#define SN_certicom_arc		"certicom-arc"
+#define NID_certicom_arc		677
+#define OBJ_certicom_arc		OBJ_identified_organization,132L
+
+#define SN_international_organizations		"international-organizations"
+#define LN_international_organizations		"International Organizations"
+#define NID_international_organizations		647
+#define OBJ_international_organizations		OBJ_joint_iso_itu_t,23L
+
+#define SN_wap		"wap"
+#define NID_wap		678
+#define OBJ_wap		OBJ_international_organizations,43L
+
+#define SN_wap_wsg		"wap-wsg"
+#define NID_wap_wsg		679
+#define OBJ_wap_wsg		OBJ_wap,13L
+
+#define SN_selected_attribute_types		"selected-attribute-types"
+#define LN_selected_attribute_types		"Selected Attribute Types"
+#define NID_selected_attribute_types		394
+#define OBJ_selected_attribute_types		OBJ_joint_iso_itu_t,5L,1L,5L
+
+#define SN_clearance		"clearance"
+#define NID_clearance		395
+#define OBJ_clearance		OBJ_selected_attribute_types,55L
+
+#define SN_ISO_US		"ISO-US"
+#define LN_ISO_US		"ISO US Member Body"
+#define NID_ISO_US		183
+#define OBJ_ISO_US		OBJ_member_body,840L
+
+#define SN_X9_57		"X9-57"
+#define LN_X9_57		"X9.57"
+#define NID_X9_57		184
+#define OBJ_X9_57		OBJ_ISO_US,10040L
+
+#define SN_X9cm		"X9cm"
+#define LN_X9cm		"X9.57 CM ?"
+#define NID_X9cm		185
+#define OBJ_X9cm		OBJ_X9_57,4L
+
+#define SN_dsa		"DSA"
+#define LN_dsa		"dsaEncryption"
+#define NID_dsa		116
+#define OBJ_dsa		OBJ_X9cm,1L
+
+#define SN_dsaWithSHA1		"DSA-SHA1"
+#define LN_dsaWithSHA1		"dsaWithSHA1"
+#define NID_dsaWithSHA1		113
+#define OBJ_dsaWithSHA1		OBJ_X9cm,3L
+
+#define SN_ansi_X9_62		"ansi-X9-62"
+#define LN_ansi_X9_62		"ANSI X9.62"
+#define NID_ansi_X9_62		405
+#define OBJ_ansi_X9_62		OBJ_ISO_US,10045L
+
+#define OBJ_X9_62_id_fieldType		OBJ_ansi_X9_62,1L
+
+#define SN_X9_62_prime_field		"prime-field"
+#define NID_X9_62_prime_field		406
+#define OBJ_X9_62_prime_field		OBJ_X9_62_id_fieldType,1L
+
+#define SN_X9_62_characteristic_two_field		"characteristic-two-field"
+#define NID_X9_62_characteristic_two_field		407
+#define OBJ_X9_62_characteristic_two_field		OBJ_X9_62_id_fieldType,2L
+
+#define SN_X9_62_id_characteristic_two_basis		"id-characteristic-two-basis"
+#define NID_X9_62_id_characteristic_two_basis		680
+#define OBJ_X9_62_id_characteristic_two_basis		OBJ_X9_62_characteristic_two_field,3L
+
+#define SN_X9_62_onBasis		"onBasis"
+#define NID_X9_62_onBasis		681
+#define OBJ_X9_62_onBasis		OBJ_X9_62_id_characteristic_two_basis,1L
+
+#define SN_X9_62_tpBasis		"tpBasis"
+#define NID_X9_62_tpBasis		682
+#define OBJ_X9_62_tpBasis		OBJ_X9_62_id_characteristic_two_basis,2L
+
+#define SN_X9_62_ppBasis		"ppBasis"
+#define NID_X9_62_ppBasis		683
+#define OBJ_X9_62_ppBasis		OBJ_X9_62_id_characteristic_two_basis,3L
+
+#define OBJ_X9_62_id_publicKeyType		OBJ_ansi_X9_62,2L
+
+#define SN_X9_62_id_ecPublicKey		"id-ecPublicKey"
+#define NID_X9_62_id_ecPublicKey		408
+#define OBJ_X9_62_id_ecPublicKey		OBJ_X9_62_id_publicKeyType,1L
+
+#define OBJ_X9_62_ellipticCurve		OBJ_ansi_X9_62,3L
+
+#define OBJ_X9_62_c_TwoCurve		OBJ_X9_62_ellipticCurve,0L
+
+#define SN_X9_62_c2pnb163v1		"c2pnb163v1"
+#define NID_X9_62_c2pnb163v1		684
+#define OBJ_X9_62_c2pnb163v1		OBJ_X9_62_c_TwoCurve,1L
+
+#define SN_X9_62_c2pnb163v2		"c2pnb163v2"
+#define NID_X9_62_c2pnb163v2		685
+#define OBJ_X9_62_c2pnb163v2		OBJ_X9_62_c_TwoCurve,2L
+
+#define SN_X9_62_c2pnb163v3		"c2pnb163v3"
+#define NID_X9_62_c2pnb163v3		686
+#define OBJ_X9_62_c2pnb163v3		OBJ_X9_62_c_TwoCurve,3L
+
+#define SN_X9_62_c2pnb176v1		"c2pnb176v1"
+#define NID_X9_62_c2pnb176v1		687
+#define OBJ_X9_62_c2pnb176v1		OBJ_X9_62_c_TwoCurve,4L
+
+#define SN_X9_62_c2tnb191v1		"c2tnb191v1"
+#define NID_X9_62_c2tnb191v1		688
+#define OBJ_X9_62_c2tnb191v1		OBJ_X9_62_c_TwoCurve,5L
+
+#define SN_X9_62_c2tnb191v2		"c2tnb191v2"
+#define NID_X9_62_c2tnb191v2		689
+#define OBJ_X9_62_c2tnb191v2		OBJ_X9_62_c_TwoCurve,6L
+
+#define SN_X9_62_c2tnb191v3		"c2tnb191v3"
+#define NID_X9_62_c2tnb191v3		690
+#define OBJ_X9_62_c2tnb191v3		OBJ_X9_62_c_TwoCurve,7L
+
+#define SN_X9_62_c2onb191v4		"c2onb191v4"
+#define NID_X9_62_c2onb191v4		691
+#define OBJ_X9_62_c2onb191v4		OBJ_X9_62_c_TwoCurve,8L
+
+#define SN_X9_62_c2onb191v5		"c2onb191v5"
+#define NID_X9_62_c2onb191v5		692
+#define OBJ_X9_62_c2onb191v5		OBJ_X9_62_c_TwoCurve,9L
+
+#define SN_X9_62_c2pnb208w1		"c2pnb208w1"
+#define NID_X9_62_c2pnb208w1		693
+#define OBJ_X9_62_c2pnb208w1		OBJ_X9_62_c_TwoCurve,10L
+
+#define SN_X9_62_c2tnb239v1		"c2tnb239v1"
+#define NID_X9_62_c2tnb239v1		694
+#define OBJ_X9_62_c2tnb239v1		OBJ_X9_62_c_TwoCurve,11L
+
+#define SN_X9_62_c2tnb239v2		"c2tnb239v2"
+#define NID_X9_62_c2tnb239v2		695
+#define OBJ_X9_62_c2tnb239v2		OBJ_X9_62_c_TwoCurve,12L
+
+#define SN_X9_62_c2tnb239v3		"c2tnb239v3"
+#define NID_X9_62_c2tnb239v3		696
+#define OBJ_X9_62_c2tnb239v3		OBJ_X9_62_c_TwoCurve,13L
+
+#define SN_X9_62_c2onb239v4		"c2onb239v4"
+#define NID_X9_62_c2onb239v4		697
+#define OBJ_X9_62_c2onb239v4		OBJ_X9_62_c_TwoCurve,14L
+
+#define SN_X9_62_c2onb239v5		"c2onb239v5"
+#define NID_X9_62_c2onb239v5		698
+#define OBJ_X9_62_c2onb239v5		OBJ_X9_62_c_TwoCurve,15L
+
+#define SN_X9_62_c2pnb272w1		"c2pnb272w1"
+#define NID_X9_62_c2pnb272w1		699
+#define OBJ_X9_62_c2pnb272w1		OBJ_X9_62_c_TwoCurve,16L
+
+#define SN_X9_62_c2pnb304w1		"c2pnb304w1"
+#define NID_X9_62_c2pnb304w1		700
+#define OBJ_X9_62_c2pnb304w1		OBJ_X9_62_c_TwoCurve,17L
+
+#define SN_X9_62_c2tnb359v1		"c2tnb359v1"
+#define NID_X9_62_c2tnb359v1		701
+#define OBJ_X9_62_c2tnb359v1		OBJ_X9_62_c_TwoCurve,18L
+
+#define SN_X9_62_c2pnb368w1		"c2pnb368w1"
+#define NID_X9_62_c2pnb368w1		702
+#define OBJ_X9_62_c2pnb368w1		OBJ_X9_62_c_TwoCurve,19L
+
+#define SN_X9_62_c2tnb431r1		"c2tnb431r1"
+#define NID_X9_62_c2tnb431r1		703
+#define OBJ_X9_62_c2tnb431r1		OBJ_X9_62_c_TwoCurve,20L
+
+#define OBJ_X9_62_primeCurve		OBJ_X9_62_ellipticCurve,1L
+
+#define SN_X9_62_prime192v1		"prime192v1"
+#define NID_X9_62_prime192v1		409
+#define OBJ_X9_62_prime192v1		OBJ_X9_62_primeCurve,1L
+
+#define SN_X9_62_prime192v2		"prime192v2"
+#define NID_X9_62_prime192v2		410
+#define OBJ_X9_62_prime192v2		OBJ_X9_62_primeCurve,2L
+
+#define SN_X9_62_prime192v3		"prime192v3"
+#define NID_X9_62_prime192v3		411
+#define OBJ_X9_62_prime192v3		OBJ_X9_62_primeCurve,3L
+
+#define SN_X9_62_prime239v1		"prime239v1"
+#define NID_X9_62_prime239v1		412
+#define OBJ_X9_62_prime239v1		OBJ_X9_62_primeCurve,4L
+
+#define SN_X9_62_prime239v2		"prime239v2"
+#define NID_X9_62_prime239v2		413
+#define OBJ_X9_62_prime239v2		OBJ_X9_62_primeCurve,5L
+
+#define SN_X9_62_prime239v3		"prime239v3"
+#define NID_X9_62_prime239v3		414
+#define OBJ_X9_62_prime239v3		OBJ_X9_62_primeCurve,6L
+
+#define SN_X9_62_prime256v1		"prime256v1"
+#define NID_X9_62_prime256v1		415
+#define OBJ_X9_62_prime256v1		OBJ_X9_62_primeCurve,7L
+
+#define OBJ_X9_62_id_ecSigType		OBJ_ansi_X9_62,4L
+
+#define SN_ecdsa_with_SHA1		"ecdsa-with-SHA1"
+#define NID_ecdsa_with_SHA1		416
+#define OBJ_ecdsa_with_SHA1		OBJ_X9_62_id_ecSigType,1L
+
+#define OBJ_secg_ellipticCurve		OBJ_certicom_arc,0L
+
+#define SN_secp112r1		"secp112r1"
+#define NID_secp112r1		704
+#define OBJ_secp112r1		OBJ_secg_ellipticCurve,6L
+
+#define SN_secp112r2		"secp112r2"
+#define NID_secp112r2		705
+#define OBJ_secp112r2		OBJ_secg_ellipticCurve,7L
+
+#define SN_secp128r1		"secp128r1"
+#define NID_secp128r1		706
+#define OBJ_secp128r1		OBJ_secg_ellipticCurve,28L
+
+#define SN_secp128r2		"secp128r2"
+#define NID_secp128r2		707
+#define OBJ_secp128r2		OBJ_secg_ellipticCurve,29L
+
+#define SN_secp160k1		"secp160k1"
+#define NID_secp160k1		708
+#define OBJ_secp160k1		OBJ_secg_ellipticCurve,9L
+
+#define SN_secp160r1		"secp160r1"
+#define NID_secp160r1		709
+#define OBJ_secp160r1		OBJ_secg_ellipticCurve,8L
+
+#define SN_secp160r2		"secp160r2"
+#define NID_secp160r2		710
+#define OBJ_secp160r2		OBJ_secg_ellipticCurve,30L
+
+#define SN_secp192k1		"secp192k1"
+#define NID_secp192k1		711
+#define OBJ_secp192k1		OBJ_secg_ellipticCurve,31L
+
+#define SN_secp224k1		"secp224k1"
+#define NID_secp224k1		712
+#define OBJ_secp224k1		OBJ_secg_ellipticCurve,32L
+
+#define SN_secp224r1		"secp224r1"
+#define NID_secp224r1		713
+#define OBJ_secp224r1		OBJ_secg_ellipticCurve,33L
+
+#define SN_secp256k1		"secp256k1"
+#define NID_secp256k1		714
+#define OBJ_secp256k1		OBJ_secg_ellipticCurve,10L
+
+#define SN_secp384r1		"secp384r1"
+#define NID_secp384r1		715
+#define OBJ_secp384r1		OBJ_secg_ellipticCurve,34L
+
+#define SN_secp521r1		"secp521r1"
+#define NID_secp521r1		716
+#define OBJ_secp521r1		OBJ_secg_ellipticCurve,35L
+
+#define SN_sect113r1		"sect113r1"
+#define NID_sect113r1		717
+#define OBJ_sect113r1		OBJ_secg_ellipticCurve,4L
+
+#define SN_sect113r2		"sect113r2"
+#define NID_sect113r2		718
+#define OBJ_sect113r2		OBJ_secg_ellipticCurve,5L
+
+#define SN_sect131r1		"sect131r1"
+#define NID_sect131r1		719
+#define OBJ_sect131r1		OBJ_secg_ellipticCurve,22L
+
+#define SN_sect131r2		"sect131r2"
+#define NID_sect131r2		720
+#define OBJ_sect131r2		OBJ_secg_ellipticCurve,23L
+
+#define SN_sect163k1		"sect163k1"
+#define NID_sect163k1		721
+#define OBJ_sect163k1		OBJ_secg_ellipticCurve,1L
+
+#define SN_sect163r1		"sect163r1"
+#define NID_sect163r1		722
+#define OBJ_sect163r1		OBJ_secg_ellipticCurve,2L
+
+#define SN_sect163r2		"sect163r2"
+#define NID_sect163r2		723
+#define OBJ_sect163r2		OBJ_secg_ellipticCurve,15L
+
+#define SN_sect193r1		"sect193r1"
+#define NID_sect193r1		724
+#define OBJ_sect193r1		OBJ_secg_ellipticCurve,24L
+
+#define SN_sect193r2		"sect193r2"
+#define NID_sect193r2		725
+#define OBJ_sect193r2		OBJ_secg_ellipticCurve,25L
+
+#define SN_sect233k1		"sect233k1"
+#define NID_sect233k1		726
+#define OBJ_sect233k1		OBJ_secg_ellipticCurve,26L
+
+#define SN_sect233r1		"sect233r1"
+#define NID_sect233r1		727
+#define OBJ_sect233r1		OBJ_secg_ellipticCurve,27L
+
+#define SN_sect239k1		"sect239k1"
+#define NID_sect239k1		728
+#define OBJ_sect239k1		OBJ_secg_ellipticCurve,3L
+
+#define SN_sect283k1		"sect283k1"
+#define NID_sect283k1		729
+#define OBJ_sect283k1		OBJ_secg_ellipticCurve,16L
+
+#define SN_sect283r1		"sect283r1"
+#define NID_sect283r1		730
+#define OBJ_sect283r1		OBJ_secg_ellipticCurve,17L
+
+#define SN_sect409k1		"sect409k1"
+#define NID_sect409k1		731
+#define OBJ_sect409k1		OBJ_secg_ellipticCurve,36L
+
+#define SN_sect409r1		"sect409r1"
+#define NID_sect409r1		732
+#define OBJ_sect409r1		OBJ_secg_ellipticCurve,37L
+
+#define SN_sect571k1		"sect571k1"
+#define NID_sect571k1		733
+#define OBJ_sect571k1		OBJ_secg_ellipticCurve,38L
+
+#define SN_sect571r1		"sect571r1"
+#define NID_sect571r1		734
+#define OBJ_sect571r1		OBJ_secg_ellipticCurve,39L
+
+#define OBJ_wap_wsg_idm_ecid		OBJ_wap_wsg,4L
+
+#define SN_wap_wsg_idm_ecid_wtls1		"wap-wsg-idm-ecid-wtls1"
+#define NID_wap_wsg_idm_ecid_wtls1		735
+#define OBJ_wap_wsg_idm_ecid_wtls1		OBJ_wap_wsg_idm_ecid,1L
+
+#define SN_wap_wsg_idm_ecid_wtls3		"wap-wsg-idm-ecid-wtls3"
+#define NID_wap_wsg_idm_ecid_wtls3		736
+#define OBJ_wap_wsg_idm_ecid_wtls3		OBJ_wap_wsg_idm_ecid,3L
+
+#define SN_wap_wsg_idm_ecid_wtls4		"wap-wsg-idm-ecid-wtls4"
+#define NID_wap_wsg_idm_ecid_wtls4		737
+#define OBJ_wap_wsg_idm_ecid_wtls4		OBJ_wap_wsg_idm_ecid,4L
+
+#define SN_wap_wsg_idm_ecid_wtls5		"wap-wsg-idm-ecid-wtls5"
+#define NID_wap_wsg_idm_ecid_wtls5		738
+#define OBJ_wap_wsg_idm_ecid_wtls5		OBJ_wap_wsg_idm_ecid,5L
+
+#define SN_wap_wsg_idm_ecid_wtls6		"wap-wsg-idm-ecid-wtls6"
+#define NID_wap_wsg_idm_ecid_wtls6		739
+#define OBJ_wap_wsg_idm_ecid_wtls6		OBJ_wap_wsg_idm_ecid,6L
+
+#define SN_wap_wsg_idm_ecid_wtls7		"wap-wsg-idm-ecid-wtls7"
+#define NID_wap_wsg_idm_ecid_wtls7		740
+#define OBJ_wap_wsg_idm_ecid_wtls7		OBJ_wap_wsg_idm_ecid,7L
+
+#define SN_wap_wsg_idm_ecid_wtls8		"wap-wsg-idm-ecid-wtls8"
+#define NID_wap_wsg_idm_ecid_wtls8		741
+#define OBJ_wap_wsg_idm_ecid_wtls8		OBJ_wap_wsg_idm_ecid,8L
+
+#define SN_wap_wsg_idm_ecid_wtls9		"wap-wsg-idm-ecid-wtls9"
+#define NID_wap_wsg_idm_ecid_wtls9		742
+#define OBJ_wap_wsg_idm_ecid_wtls9		OBJ_wap_wsg_idm_ecid,9L
+
+#define SN_wap_wsg_idm_ecid_wtls10		"wap-wsg-idm-ecid-wtls10"
+#define NID_wap_wsg_idm_ecid_wtls10		743
+#define OBJ_wap_wsg_idm_ecid_wtls10		OBJ_wap_wsg_idm_ecid,10L
+
+#define SN_wap_wsg_idm_ecid_wtls11		"wap-wsg-idm-ecid-wtls11"
+#define NID_wap_wsg_idm_ecid_wtls11		744
+#define OBJ_wap_wsg_idm_ecid_wtls11		OBJ_wap_wsg_idm_ecid,11L
+
+#define SN_wap_wsg_idm_ecid_wtls12		"wap-wsg-idm-ecid-wtls12"
+#define NID_wap_wsg_idm_ecid_wtls12		745
+#define OBJ_wap_wsg_idm_ecid_wtls12		OBJ_wap_wsg_idm_ecid,12L
+
+#define SN_cast5_cbc		"CAST5-CBC"
+#define LN_cast5_cbc		"cast5-cbc"
+#define NID_cast5_cbc		108
+#define OBJ_cast5_cbc		OBJ_ISO_US,113533L,7L,66L,10L
+
+#define SN_cast5_ecb		"CAST5-ECB"
+#define LN_cast5_ecb		"cast5-ecb"
+#define NID_cast5_ecb		109
+
+#define SN_cast5_cfb64		"CAST5-CFB"
+#define LN_cast5_cfb64		"cast5-cfb"
+#define NID_cast5_cfb64		110
+
+#define SN_cast5_ofb64		"CAST5-OFB"
+#define LN_cast5_ofb64		"cast5-ofb"
+#define NID_cast5_ofb64		111
+
+#define LN_pbeWithMD5AndCast5_CBC		"pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC		112
+#define OBJ_pbeWithMD5AndCast5_CBC		OBJ_ISO_US,113533L,7L,66L,12L
+
+#define SN_rsadsi		"rsadsi"
+#define LN_rsadsi		"RSA Data Security, Inc."
+#define NID_rsadsi		1
+#define OBJ_rsadsi		OBJ_ISO_US,113549L
+
+#define SN_pkcs		"pkcs"
+#define LN_pkcs		"RSA Data Security, Inc. PKCS"
+#define NID_pkcs		2
+#define OBJ_pkcs		OBJ_rsadsi,1L
+
+#define SN_pkcs1		"pkcs1"
+#define NID_pkcs1		186
+#define OBJ_pkcs1		OBJ_pkcs,1L
+
+#define LN_rsaEncryption		"rsaEncryption"
+#define NID_rsaEncryption		6
+#define OBJ_rsaEncryption		OBJ_pkcs1,1L
+
+#define SN_md2WithRSAEncryption		"RSA-MD2"
+#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption		7
+#define OBJ_md2WithRSAEncryption		OBJ_pkcs1,2L
+
+#define SN_md4WithRSAEncryption		"RSA-MD4"
+#define LN_md4WithRSAEncryption		"md4WithRSAEncryption"
+#define NID_md4WithRSAEncryption		396
+#define OBJ_md4WithRSAEncryption		OBJ_pkcs1,3L
+
+#define SN_md5WithRSAEncryption		"RSA-MD5"
+#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption		8
+#define OBJ_md5WithRSAEncryption		OBJ_pkcs1,4L
+
+#define SN_sha1WithRSAEncryption		"RSA-SHA1"
+#define LN_sha1WithRSAEncryption		"sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption		65
+#define OBJ_sha1WithRSAEncryption		OBJ_pkcs1,5L
+
+#define SN_sha256WithRSAEncryption		"RSA-SHA256"
+#define LN_sha256WithRSAEncryption		"sha256WithRSAEncryption"
+#define NID_sha256WithRSAEncryption		668
+#define OBJ_sha256WithRSAEncryption		OBJ_pkcs1,11L
+
+#define SN_sha384WithRSAEncryption		"RSA-SHA384"
+#define LN_sha384WithRSAEncryption		"sha384WithRSAEncryption"
+#define NID_sha384WithRSAEncryption		669
+#define OBJ_sha384WithRSAEncryption		OBJ_pkcs1,12L
+
+#define SN_sha512WithRSAEncryption		"RSA-SHA512"
+#define LN_sha512WithRSAEncryption		"sha512WithRSAEncryption"
+#define NID_sha512WithRSAEncryption		670
+#define OBJ_sha512WithRSAEncryption		OBJ_pkcs1,13L
+
+#define SN_sha224WithRSAEncryption		"RSA-SHA224"
+#define LN_sha224WithRSAEncryption		"sha224WithRSAEncryption"
+#define NID_sha224WithRSAEncryption		671
+#define OBJ_sha224WithRSAEncryption		OBJ_pkcs1,14L
+
+#define SN_pkcs3		"pkcs3"
+#define NID_pkcs3		27
+#define OBJ_pkcs3		OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement		"dhKeyAgreement"
+#define NID_dhKeyAgreement		28
+#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
+
+#define SN_pkcs5		"pkcs5"
+#define NID_pkcs5		187
+#define OBJ_pkcs5		OBJ_pkcs,5L
+
+#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC		9
+#define OBJ_pbeWithMD2AndDES_CBC		OBJ_pkcs5,1L
+
+#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC		10
+#define OBJ_pbeWithMD5AndDES_CBC		OBJ_pkcs5,3L
+
+#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC		168
+#define OBJ_pbeWithMD2AndRC2_CBC		OBJ_pkcs5,4L
+
+#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC		169
+#define OBJ_pbeWithMD5AndRC2_CBC		OBJ_pkcs5,6L
+
+#define SN_pbeWithSHA1AndDES_CBC		"PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC		"pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC		170
+#define OBJ_pbeWithSHA1AndDES_CBC		OBJ_pkcs5,10L
+
+#define SN_pbeWithSHA1AndRC2_CBC		"PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC		"pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC		68
+#define OBJ_pbeWithSHA1AndRC2_CBC		OBJ_pkcs5,11L
+
+#define LN_id_pbkdf2		"PBKDF2"
+#define NID_id_pbkdf2		69
+#define OBJ_id_pbkdf2		OBJ_pkcs5,12L
+
+#define LN_pbes2		"PBES2"
+#define NID_pbes2		161
+#define OBJ_pbes2		OBJ_pkcs5,13L
+
+#define LN_pbmac1		"PBMAC1"
+#define NID_pbmac1		162
+#define OBJ_pbmac1		OBJ_pkcs5,14L
+
+#define SN_pkcs7		"pkcs7"
+#define NID_pkcs7		20
+#define OBJ_pkcs7		OBJ_pkcs,7L
+
+#define LN_pkcs7_data		"pkcs7-data"
+#define NID_pkcs7_data		21
+#define OBJ_pkcs7_data		OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed		"pkcs7-signedData"
+#define NID_pkcs7_signed		22
+#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
+#define NID_pkcs7_enveloped		23
+#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped		"pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped		24
+#define OBJ_pkcs7_signedAndEnveloped		OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest		"pkcs7-digestData"
+#define NID_pkcs7_digest		25
+#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
+#define NID_pkcs7_encrypted		26
+#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
+
+#define SN_pkcs9		"pkcs9"
+#define NID_pkcs9		47
+#define OBJ_pkcs9		OBJ_pkcs,9L
+
+#define LN_pkcs9_emailAddress		"emailAddress"
+#define NID_pkcs9_emailAddress		48
+#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName		"unstructuredName"
+#define NID_pkcs9_unstructuredName		49
+#define OBJ_pkcs9_unstructuredName		OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType		"contentType"
+#define NID_pkcs9_contentType		50
+#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest		"messageDigest"
+#define NID_pkcs9_messageDigest		51
+#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime		"signingTime"
+#define NID_pkcs9_signingTime		52
+#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature		"countersignature"
+#define NID_pkcs9_countersignature		53
+#define OBJ_pkcs9_countersignature		OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword		"challengePassword"
+#define NID_pkcs9_challengePassword		54
+#define OBJ_pkcs9_challengePassword		OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress		"unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress		55
+#define OBJ_pkcs9_unstructuredAddress		OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes		"extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes		56
+#define OBJ_pkcs9_extCertAttributes		OBJ_pkcs9,9L
+
+#define SN_ext_req		"extReq"
+#define LN_ext_req		"Extension Request"
+#define NID_ext_req		172
+#define OBJ_ext_req		OBJ_pkcs9,14L
+
+#define SN_SMIMECapabilities		"SMIME-CAPS"
+#define LN_SMIMECapabilities		"S/MIME Capabilities"
+#define NID_SMIMECapabilities		167
+#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
+
+#define SN_SMIME		"SMIME"
+#define LN_SMIME		"S/MIME"
+#define NID_SMIME		188
+#define OBJ_SMIME		OBJ_pkcs9,16L
+
+#define SN_id_smime_mod		"id-smime-mod"
+#define NID_id_smime_mod		189
+#define OBJ_id_smime_mod		OBJ_SMIME,0L
+
+#define SN_id_smime_ct		"id-smime-ct"
+#define NID_id_smime_ct		190
+#define OBJ_id_smime_ct		OBJ_SMIME,1L
+
+#define SN_id_smime_aa		"id-smime-aa"
+#define NID_id_smime_aa		191
+#define OBJ_id_smime_aa		OBJ_SMIME,2L
+
+#define SN_id_smime_alg		"id-smime-alg"
+#define NID_id_smime_alg		192
+#define OBJ_id_smime_alg		OBJ_SMIME,3L
+
+#define SN_id_smime_cd		"id-smime-cd"
+#define NID_id_smime_cd		193
+#define OBJ_id_smime_cd		OBJ_SMIME,4L
+
+#define SN_id_smime_spq		"id-smime-spq"
+#define NID_id_smime_spq		194
+#define OBJ_id_smime_spq		OBJ_SMIME,5L
+
+#define SN_id_smime_cti		"id-smime-cti"
+#define NID_id_smime_cti		195
+#define OBJ_id_smime_cti		OBJ_SMIME,6L
+
+#define SN_id_smime_mod_cms		"id-smime-mod-cms"
+#define NID_id_smime_mod_cms		196
+#define OBJ_id_smime_mod_cms		OBJ_id_smime_mod,1L
+
+#define SN_id_smime_mod_ess		"id-smime-mod-ess"
+#define NID_id_smime_mod_ess		197
+#define OBJ_id_smime_mod_ess		OBJ_id_smime_mod,2L
+
+#define SN_id_smime_mod_oid		"id-smime-mod-oid"
+#define NID_id_smime_mod_oid		198
+#define OBJ_id_smime_mod_oid		OBJ_id_smime_mod,3L
+
+#define SN_id_smime_mod_msg_v3		"id-smime-mod-msg-v3"
+#define NID_id_smime_mod_msg_v3		199
+#define OBJ_id_smime_mod_msg_v3		OBJ_id_smime_mod,4L
+
+#define SN_id_smime_mod_ets_eSignature_88		"id-smime-mod-ets-eSignature-88"
+#define NID_id_smime_mod_ets_eSignature_88		200
+#define OBJ_id_smime_mod_ets_eSignature_88		OBJ_id_smime_mod,5L
+
+#define SN_id_smime_mod_ets_eSignature_97		"id-smime-mod-ets-eSignature-97"
+#define NID_id_smime_mod_ets_eSignature_97		201
+#define OBJ_id_smime_mod_ets_eSignature_97		OBJ_id_smime_mod,6L
+
+#define SN_id_smime_mod_ets_eSigPolicy_88		"id-smime-mod-ets-eSigPolicy-88"
+#define NID_id_smime_mod_ets_eSigPolicy_88		202
+#define OBJ_id_smime_mod_ets_eSigPolicy_88		OBJ_id_smime_mod,7L
+
+#define SN_id_smime_mod_ets_eSigPolicy_97		"id-smime-mod-ets-eSigPolicy-97"
+#define NID_id_smime_mod_ets_eSigPolicy_97		203
+#define OBJ_id_smime_mod_ets_eSigPolicy_97		OBJ_id_smime_mod,8L
+
+#define SN_id_smime_ct_receipt		"id-smime-ct-receipt"
+#define NID_id_smime_ct_receipt		204
+#define OBJ_id_smime_ct_receipt		OBJ_id_smime_ct,1L
+
+#define SN_id_smime_ct_authData		"id-smime-ct-authData"
+#define NID_id_smime_ct_authData		205
+#define OBJ_id_smime_ct_authData		OBJ_id_smime_ct,2L
+
+#define SN_id_smime_ct_publishCert		"id-smime-ct-publishCert"
+#define NID_id_smime_ct_publishCert		206
+#define OBJ_id_smime_ct_publishCert		OBJ_id_smime_ct,3L
+
+#define SN_id_smime_ct_TSTInfo		"id-smime-ct-TSTInfo"
+#define NID_id_smime_ct_TSTInfo		207
+#define OBJ_id_smime_ct_TSTInfo		OBJ_id_smime_ct,4L
+
+#define SN_id_smime_ct_TDTInfo		"id-smime-ct-TDTInfo"
+#define NID_id_smime_ct_TDTInfo		208
+#define OBJ_id_smime_ct_TDTInfo		OBJ_id_smime_ct,5L
+
+#define SN_id_smime_ct_contentInfo		"id-smime-ct-contentInfo"
+#define NID_id_smime_ct_contentInfo		209
+#define OBJ_id_smime_ct_contentInfo		OBJ_id_smime_ct,6L
+
+#define SN_id_smime_ct_DVCSRequestData		"id-smime-ct-DVCSRequestData"
+#define NID_id_smime_ct_DVCSRequestData		210
+#define OBJ_id_smime_ct_DVCSRequestData		OBJ_id_smime_ct,7L
+
+#define SN_id_smime_ct_DVCSResponseData		"id-smime-ct-DVCSResponseData"
+#define NID_id_smime_ct_DVCSResponseData		211
+#define OBJ_id_smime_ct_DVCSResponseData		OBJ_id_smime_ct,8L
+
+#define SN_id_smime_aa_receiptRequest		"id-smime-aa-receiptRequest"
+#define NID_id_smime_aa_receiptRequest		212
+#define OBJ_id_smime_aa_receiptRequest		OBJ_id_smime_aa,1L
+
+#define SN_id_smime_aa_securityLabel		"id-smime-aa-securityLabel"
+#define NID_id_smime_aa_securityLabel		213
+#define OBJ_id_smime_aa_securityLabel		OBJ_id_smime_aa,2L
+
+#define SN_id_smime_aa_mlExpandHistory		"id-smime-aa-mlExpandHistory"
+#define NID_id_smime_aa_mlExpandHistory		214
+#define OBJ_id_smime_aa_mlExpandHistory		OBJ_id_smime_aa,3L
+
+#define SN_id_smime_aa_contentHint		"id-smime-aa-contentHint"
+#define NID_id_smime_aa_contentHint		215
+#define OBJ_id_smime_aa_contentHint		OBJ_id_smime_aa,4L
+
+#define SN_id_smime_aa_msgSigDigest		"id-smime-aa-msgSigDigest"
+#define NID_id_smime_aa_msgSigDigest		216
+#define OBJ_id_smime_aa_msgSigDigest		OBJ_id_smime_aa,5L
+
+#define SN_id_smime_aa_encapContentType		"id-smime-aa-encapContentType"
+#define NID_id_smime_aa_encapContentType		217
+#define OBJ_id_smime_aa_encapContentType		OBJ_id_smime_aa,6L
+
+#define SN_id_smime_aa_contentIdentifier		"id-smime-aa-contentIdentifier"
+#define NID_id_smime_aa_contentIdentifier		218
+#define OBJ_id_smime_aa_contentIdentifier		OBJ_id_smime_aa,7L
+
+#define SN_id_smime_aa_macValue		"id-smime-aa-macValue"
+#define NID_id_smime_aa_macValue		219
+#define OBJ_id_smime_aa_macValue		OBJ_id_smime_aa,8L
+
+#define SN_id_smime_aa_equivalentLabels		"id-smime-aa-equivalentLabels"
+#define NID_id_smime_aa_equivalentLabels		220
+#define OBJ_id_smime_aa_equivalentLabels		OBJ_id_smime_aa,9L
+
+#define SN_id_smime_aa_contentReference		"id-smime-aa-contentReference"
+#define NID_id_smime_aa_contentReference		221
+#define OBJ_id_smime_aa_contentReference		OBJ_id_smime_aa,10L
+
+#define SN_id_smime_aa_encrypKeyPref		"id-smime-aa-encrypKeyPref"
+#define NID_id_smime_aa_encrypKeyPref		222
+#define OBJ_id_smime_aa_encrypKeyPref		OBJ_id_smime_aa,11L
+
+#define SN_id_smime_aa_signingCertificate		"id-smime-aa-signingCertificate"
+#define NID_id_smime_aa_signingCertificate		223
+#define OBJ_id_smime_aa_signingCertificate		OBJ_id_smime_aa,12L
+
+#define SN_id_smime_aa_smimeEncryptCerts		"id-smime-aa-smimeEncryptCerts"
+#define NID_id_smime_aa_smimeEncryptCerts		224
+#define OBJ_id_smime_aa_smimeEncryptCerts		OBJ_id_smime_aa,13L
+
+#define SN_id_smime_aa_timeStampToken		"id-smime-aa-timeStampToken"
+#define NID_id_smime_aa_timeStampToken		225
+#define OBJ_id_smime_aa_timeStampToken		OBJ_id_smime_aa,14L
+
+#define SN_id_smime_aa_ets_sigPolicyId		"id-smime-aa-ets-sigPolicyId"
+#define NID_id_smime_aa_ets_sigPolicyId		226
+#define OBJ_id_smime_aa_ets_sigPolicyId		OBJ_id_smime_aa,15L
+
+#define SN_id_smime_aa_ets_commitmentType		"id-smime-aa-ets-commitmentType"
+#define NID_id_smime_aa_ets_commitmentType		227
+#define OBJ_id_smime_aa_ets_commitmentType		OBJ_id_smime_aa,16L
+
+#define SN_id_smime_aa_ets_signerLocation		"id-smime-aa-ets-signerLocation"
+#define NID_id_smime_aa_ets_signerLocation		228
+#define OBJ_id_smime_aa_ets_signerLocation		OBJ_id_smime_aa,17L
+
+#define SN_id_smime_aa_ets_signerAttr		"id-smime-aa-ets-signerAttr"
+#define NID_id_smime_aa_ets_signerAttr		229
+#define OBJ_id_smime_aa_ets_signerAttr		OBJ_id_smime_aa,18L
+
+#define SN_id_smime_aa_ets_otherSigCert		"id-smime-aa-ets-otherSigCert"
+#define NID_id_smime_aa_ets_otherSigCert		230
+#define OBJ_id_smime_aa_ets_otherSigCert		OBJ_id_smime_aa,19L
+
+#define SN_id_smime_aa_ets_contentTimestamp		"id-smime-aa-ets-contentTimestamp"
+#define NID_id_smime_aa_ets_contentTimestamp		231
+#define OBJ_id_smime_aa_ets_contentTimestamp		OBJ_id_smime_aa,20L
+
+#define SN_id_smime_aa_ets_CertificateRefs		"id-smime-aa-ets-CertificateRefs"
+#define NID_id_smime_aa_ets_CertificateRefs		232
+#define OBJ_id_smime_aa_ets_CertificateRefs		OBJ_id_smime_aa,21L
+
+#define SN_id_smime_aa_ets_RevocationRefs		"id-smime-aa-ets-RevocationRefs"
+#define NID_id_smime_aa_ets_RevocationRefs		233
+#define OBJ_id_smime_aa_ets_RevocationRefs		OBJ_id_smime_aa,22L
+
+#define SN_id_smime_aa_ets_certValues		"id-smime-aa-ets-certValues"
+#define NID_id_smime_aa_ets_certValues		234
+#define OBJ_id_smime_aa_ets_certValues		OBJ_id_smime_aa,23L
+
+#define SN_id_smime_aa_ets_revocationValues		"id-smime-aa-ets-revocationValues"
+#define NID_id_smime_aa_ets_revocationValues		235
+#define OBJ_id_smime_aa_ets_revocationValues		OBJ_id_smime_aa,24L
+
+#define SN_id_smime_aa_ets_escTimeStamp		"id-smime-aa-ets-escTimeStamp"
+#define NID_id_smime_aa_ets_escTimeStamp		236
+#define OBJ_id_smime_aa_ets_escTimeStamp		OBJ_id_smime_aa,25L
+
+#define SN_id_smime_aa_ets_certCRLTimestamp		"id-smime-aa-ets-certCRLTimestamp"
+#define NID_id_smime_aa_ets_certCRLTimestamp		237
+#define OBJ_id_smime_aa_ets_certCRLTimestamp		OBJ_id_smime_aa,26L
+
+#define SN_id_smime_aa_ets_archiveTimeStamp		"id-smime-aa-ets-archiveTimeStamp"
+#define NID_id_smime_aa_ets_archiveTimeStamp		238
+#define OBJ_id_smime_aa_ets_archiveTimeStamp		OBJ_id_smime_aa,27L
+
+#define SN_id_smime_aa_signatureType		"id-smime-aa-signatureType"
+#define NID_id_smime_aa_signatureType		239
+#define OBJ_id_smime_aa_signatureType		OBJ_id_smime_aa,28L
+
+#define SN_id_smime_aa_dvcs_dvc		"id-smime-aa-dvcs-dvc"
+#define NID_id_smime_aa_dvcs_dvc		240
+#define OBJ_id_smime_aa_dvcs_dvc		OBJ_id_smime_aa,29L
+
+#define SN_id_smime_alg_ESDHwith3DES		"id-smime-alg-ESDHwith3DES"
+#define NID_id_smime_alg_ESDHwith3DES		241
+#define OBJ_id_smime_alg_ESDHwith3DES		OBJ_id_smime_alg,1L
+
+#define SN_id_smime_alg_ESDHwithRC2		"id-smime-alg-ESDHwithRC2"
+#define NID_id_smime_alg_ESDHwithRC2		242
+#define OBJ_id_smime_alg_ESDHwithRC2		OBJ_id_smime_alg,2L
+
+#define SN_id_smime_alg_3DESwrap		"id-smime-alg-3DESwrap"
+#define NID_id_smime_alg_3DESwrap		243
+#define OBJ_id_smime_alg_3DESwrap		OBJ_id_smime_alg,3L
+
+#define SN_id_smime_alg_RC2wrap		"id-smime-alg-RC2wrap"
+#define NID_id_smime_alg_RC2wrap		244
+#define OBJ_id_smime_alg_RC2wrap		OBJ_id_smime_alg,4L
+
+#define SN_id_smime_alg_ESDH		"id-smime-alg-ESDH"
+#define NID_id_smime_alg_ESDH		245
+#define OBJ_id_smime_alg_ESDH		OBJ_id_smime_alg,5L
+
+#define SN_id_smime_alg_CMS3DESwrap		"id-smime-alg-CMS3DESwrap"
+#define NID_id_smime_alg_CMS3DESwrap		246
+#define OBJ_id_smime_alg_CMS3DESwrap		OBJ_id_smime_alg,6L
+
+#define SN_id_smime_alg_CMSRC2wrap		"id-smime-alg-CMSRC2wrap"
+#define NID_id_smime_alg_CMSRC2wrap		247
+#define OBJ_id_smime_alg_CMSRC2wrap		OBJ_id_smime_alg,7L
+
+#define SN_id_smime_cd_ldap		"id-smime-cd-ldap"
+#define NID_id_smime_cd_ldap		248
+#define OBJ_id_smime_cd_ldap		OBJ_id_smime_cd,1L
+
+#define SN_id_smime_spq_ets_sqt_uri		"id-smime-spq-ets-sqt-uri"
+#define NID_id_smime_spq_ets_sqt_uri		249
+#define OBJ_id_smime_spq_ets_sqt_uri		OBJ_id_smime_spq,1L
+
+#define SN_id_smime_spq_ets_sqt_unotice		"id-smime-spq-ets-sqt-unotice"
+#define NID_id_smime_spq_ets_sqt_unotice		250
+#define OBJ_id_smime_spq_ets_sqt_unotice		OBJ_id_smime_spq,2L
+
+#define SN_id_smime_cti_ets_proofOfOrigin		"id-smime-cti-ets-proofOfOrigin"
+#define NID_id_smime_cti_ets_proofOfOrigin		251
+#define OBJ_id_smime_cti_ets_proofOfOrigin		OBJ_id_smime_cti,1L
+
+#define SN_id_smime_cti_ets_proofOfReceipt		"id-smime-cti-ets-proofOfReceipt"
+#define NID_id_smime_cti_ets_proofOfReceipt		252
+#define OBJ_id_smime_cti_ets_proofOfReceipt		OBJ_id_smime_cti,2L
+
+#define SN_id_smime_cti_ets_proofOfDelivery		"id-smime-cti-ets-proofOfDelivery"
+#define NID_id_smime_cti_ets_proofOfDelivery		253
+#define OBJ_id_smime_cti_ets_proofOfDelivery		OBJ_id_smime_cti,3L
+
+#define SN_id_smime_cti_ets_proofOfSender		"id-smime-cti-ets-proofOfSender"
+#define NID_id_smime_cti_ets_proofOfSender		254
+#define OBJ_id_smime_cti_ets_proofOfSender		OBJ_id_smime_cti,4L
+
+#define SN_id_smime_cti_ets_proofOfApproval		"id-smime-cti-ets-proofOfApproval"
+#define NID_id_smime_cti_ets_proofOfApproval		255
+#define OBJ_id_smime_cti_ets_proofOfApproval		OBJ_id_smime_cti,5L
+
+#define SN_id_smime_cti_ets_proofOfCreation		"id-smime-cti-ets-proofOfCreation"
+#define NID_id_smime_cti_ets_proofOfCreation		256
+#define OBJ_id_smime_cti_ets_proofOfCreation		OBJ_id_smime_cti,6L
+
+#define LN_friendlyName		"friendlyName"
+#define NID_friendlyName		156
+#define OBJ_friendlyName		OBJ_pkcs9,20L
+
+#define LN_localKeyID		"localKeyID"
+#define NID_localKeyID		157
+#define OBJ_localKeyID		OBJ_pkcs9,21L
+
+#define SN_ms_csp_name		"CSPName"
+#define LN_ms_csp_name		"Microsoft CSP Name"
+#define NID_ms_csp_name		417
+#define OBJ_ms_csp_name		1L,3L,6L,1L,4L,1L,311L,17L,1L
+
+#define OBJ_certTypes		OBJ_pkcs9,22L
+
+#define LN_x509Certificate		"x509Certificate"
+#define NID_x509Certificate		158
+#define OBJ_x509Certificate		OBJ_certTypes,1L
+
+#define LN_sdsiCertificate		"sdsiCertificate"
+#define NID_sdsiCertificate		159
+#define OBJ_sdsiCertificate		OBJ_certTypes,2L
+
+#define OBJ_crlTypes		OBJ_pkcs9,23L
+
+#define LN_x509Crl		"x509Crl"
+#define NID_x509Crl		160
+#define OBJ_x509Crl		OBJ_crlTypes,1L
+
+#define OBJ_pkcs12		OBJ_pkcs,12L
+
+#define OBJ_pkcs12_pbeids		OBJ_pkcs12,1L
+
+#define SN_pbe_WithSHA1And128BitRC4		"PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4		"pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4		144
+#define OBJ_pbe_WithSHA1And128BitRC4		OBJ_pkcs12_pbeids,1L
+
+#define SN_pbe_WithSHA1And40BitRC4		"PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4		"pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4		145
+#define OBJ_pbe_WithSHA1And40BitRC4		OBJ_pkcs12_pbeids,2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC		"PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC		"pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC		146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC		"PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC		"pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC		147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC		OBJ_pkcs12_pbeids,4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC		148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC		OBJ_pkcs12_pbeids,5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC		"PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC		"pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC		149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC		OBJ_pkcs12_pbeids,6L
+
+#define OBJ_pkcs12_Version1		OBJ_pkcs12,10L
+
+#define OBJ_pkcs12_BagIds		OBJ_pkcs12_Version1,1L
+
+#define LN_keyBag		"keyBag"
+#define NID_keyBag		150
+#define OBJ_keyBag		OBJ_pkcs12_BagIds,1L
+
+#define LN_pkcs8ShroudedKeyBag		"pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag		151
+#define OBJ_pkcs8ShroudedKeyBag		OBJ_pkcs12_BagIds,2L
+
+#define LN_certBag		"certBag"
+#define NID_certBag		152
+#define OBJ_certBag		OBJ_pkcs12_BagIds,3L
+
+#define LN_crlBag		"crlBag"
+#define NID_crlBag		153
+#define OBJ_crlBag		OBJ_pkcs12_BagIds,4L
+
+#define LN_secretBag		"secretBag"
+#define NID_secretBag		154
+#define OBJ_secretBag		OBJ_pkcs12_BagIds,5L
+
+#define LN_safeContentsBag		"safeContentsBag"
+#define NID_safeContentsBag		155
+#define OBJ_safeContentsBag		OBJ_pkcs12_BagIds,6L
+
+#define SN_md2		"MD2"
+#define LN_md2		"md2"
+#define NID_md2		3
+#define OBJ_md2		OBJ_rsadsi,2L,2L
+
+#define SN_md4		"MD4"
+#define LN_md4		"md4"
+#define NID_md4		257
+#define OBJ_md4		OBJ_rsadsi,2L,4L
+
+#define SN_md5		"MD5"
+#define LN_md5		"md5"
+#define NID_md5		4
+#define OBJ_md5		OBJ_rsadsi,2L,5L
+
+#define SN_md5_sha1		"MD5-SHA1"
+#define LN_md5_sha1		"md5-sha1"
+#define NID_md5_sha1		114
+
+#define LN_hmacWithSHA1		"hmacWithSHA1"
+#define NID_hmacWithSHA1		163
+#define OBJ_hmacWithSHA1		OBJ_rsadsi,2L,7L
+
+#define SN_rc2_cbc		"RC2-CBC"
+#define LN_rc2_cbc		"rc2-cbc"
+#define NID_rc2_cbc		37
+#define OBJ_rc2_cbc		OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb		"RC2-ECB"
+#define LN_rc2_ecb		"rc2-ecb"
+#define NID_rc2_ecb		38
+
+#define SN_rc2_cfb64		"RC2-CFB"
+#define LN_rc2_cfb64		"rc2-cfb"
+#define NID_rc2_cfb64		39
+
+#define SN_rc2_ofb64		"RC2-OFB"
+#define LN_rc2_ofb64		"rc2-ofb"
+#define NID_rc2_ofb64		40
+
+#define SN_rc2_40_cbc		"RC2-40-CBC"
+#define LN_rc2_40_cbc		"rc2-40-cbc"
+#define NID_rc2_40_cbc		98
+
+#define SN_rc2_64_cbc		"RC2-64-CBC"
+#define LN_rc2_64_cbc		"rc2-64-cbc"
+#define NID_rc2_64_cbc		166
+
+#define SN_rc4		"RC4"
+#define LN_rc4		"rc4"
+#define NID_rc4		5
+#define OBJ_rc4		OBJ_rsadsi,3L,4L
+
+#define SN_rc4_40		"RC4-40"
+#define LN_rc4_40		"rc4-40"
+#define NID_rc4_40		97
+
+#define SN_des_ede3_cbc		"DES-EDE3-CBC"
+#define LN_des_ede3_cbc		"des-ede3-cbc"
+#define NID_des_ede3_cbc		44
+#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
+
+#define SN_rc5_cbc		"RC5-CBC"
+#define LN_rc5_cbc		"rc5-cbc"
+#define NID_rc5_cbc		120
+#define OBJ_rc5_cbc		OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb		"RC5-ECB"
+#define LN_rc5_ecb		"rc5-ecb"
+#define NID_rc5_ecb		121
+
+#define SN_rc5_cfb64		"RC5-CFB"
+#define LN_rc5_cfb64		"rc5-cfb"
+#define NID_rc5_cfb64		122
+
+#define SN_rc5_ofb64		"RC5-OFB"
+#define LN_rc5_ofb64		"rc5-ofb"
+#define NID_rc5_ofb64		123
+
+#define SN_ms_ext_req		"msExtReq"
+#define LN_ms_ext_req		"Microsoft Extension Request"
+#define NID_ms_ext_req		171
+#define OBJ_ms_ext_req		1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define SN_ms_code_ind		"msCodeInd"
+#define LN_ms_code_ind		"Microsoft Individual Code Signing"
+#define NID_ms_code_ind		134
+#define OBJ_ms_code_ind		1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com		"msCodeCom"
+#define LN_ms_code_com		"Microsoft Commercial Code Signing"
+#define NID_ms_code_com		135
+#define OBJ_ms_code_com		1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign		"msCTLSign"
+#define LN_ms_ctl_sign		"Microsoft Trust List Signing"
+#define NID_ms_ctl_sign		136
+#define OBJ_ms_ctl_sign		1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc		"msSGC"
+#define LN_ms_sgc		"Microsoft Server Gated Crypto"
+#define NID_ms_sgc		137
+#define OBJ_ms_sgc		1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs		"msEFS"
+#define LN_ms_efs		"Microsoft Encrypted File System"
+#define NID_ms_efs		138
+#define OBJ_ms_efs		1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+#define SN_ms_smartcard_login		"msSmartcardLogin"
+#define LN_ms_smartcard_login		"Microsoft Smartcardlogin"
+#define NID_ms_smartcard_login		648
+#define OBJ_ms_smartcard_login		1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
+
+#define SN_ms_upn		"msUPN"
+#define LN_ms_upn		"Microsoft Universal Principal Name"
+#define NID_ms_upn		649
+#define OBJ_ms_upn		1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
+
+#define SN_idea_cbc		"IDEA-CBC"
+#define LN_idea_cbc		"idea-cbc"
+#define NID_idea_cbc		34
+#define OBJ_idea_cbc		1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_ecb		"IDEA-ECB"
+#define LN_idea_ecb		"idea-ecb"
+#define NID_idea_ecb		36
+
+#define SN_idea_cfb64		"IDEA-CFB"
+#define LN_idea_cfb64		"idea-cfb"
+#define NID_idea_cfb64		35
+
+#define SN_idea_ofb64		"IDEA-OFB"
+#define LN_idea_ofb64		"idea-ofb"
+#define NID_idea_ofb64		46
+
+#define SN_bf_cbc		"BF-CBC"
+#define LN_bf_cbc		"bf-cbc"
+#define NID_bf_cbc		91
+#define OBJ_bf_cbc		1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb		"BF-ECB"
+#define LN_bf_ecb		"bf-ecb"
+#define NID_bf_ecb		92
+
+#define SN_bf_cfb64		"BF-CFB"
+#define LN_bf_cfb64		"bf-cfb"
+#define NID_bf_cfb64		93
+
+#define SN_bf_ofb64		"BF-OFB"
+#define LN_bf_ofb64		"bf-ofb"
+#define NID_bf_ofb64		94
+
+#define SN_id_pkix		"PKIX"
+#define NID_id_pkix		127
+#define OBJ_id_pkix		1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_pkix_mod		"id-pkix-mod"
+#define NID_id_pkix_mod		258
+#define OBJ_id_pkix_mod		OBJ_id_pkix,0L
+
+#define SN_id_pe		"id-pe"
+#define NID_id_pe		175
+#define OBJ_id_pe		OBJ_id_pkix,1L
+
+#define SN_id_qt		"id-qt"
+#define NID_id_qt		259
+#define OBJ_id_qt		OBJ_id_pkix,2L
+
+#define SN_id_kp		"id-kp"
+#define NID_id_kp		128
+#define OBJ_id_kp		OBJ_id_pkix,3L
+
+#define SN_id_it		"id-it"
+#define NID_id_it		260
+#define OBJ_id_it		OBJ_id_pkix,4L
+
+#define SN_id_pkip		"id-pkip"
+#define NID_id_pkip		261
+#define OBJ_id_pkip		OBJ_id_pkix,5L
+
+#define SN_id_alg		"id-alg"
+#define NID_id_alg		262
+#define OBJ_id_alg		OBJ_id_pkix,6L
+
+#define SN_id_cmc		"id-cmc"
+#define NID_id_cmc		263
+#define OBJ_id_cmc		OBJ_id_pkix,7L
+
+#define SN_id_on		"id-on"
+#define NID_id_on		264
+#define OBJ_id_on		OBJ_id_pkix,8L
+
+#define SN_id_pda		"id-pda"
+#define NID_id_pda		265
+#define OBJ_id_pda		OBJ_id_pkix,9L
+
+#define SN_id_aca		"id-aca"
+#define NID_id_aca		266
+#define OBJ_id_aca		OBJ_id_pkix,10L
+
+#define SN_id_qcs		"id-qcs"
+#define NID_id_qcs		267
+#define OBJ_id_qcs		OBJ_id_pkix,11L
+
+#define SN_id_cct		"id-cct"
+#define NID_id_cct		268
+#define OBJ_id_cct		OBJ_id_pkix,12L
+
+#define SN_id_ppl		"id-ppl"
+#define NID_id_ppl		662
+#define OBJ_id_ppl		OBJ_id_pkix,21L
+
+#define SN_id_ad		"id-ad"
+#define NID_id_ad		176
+#define OBJ_id_ad		OBJ_id_pkix,48L
+
+#define SN_id_pkix1_explicit_88		"id-pkix1-explicit-88"
+#define NID_id_pkix1_explicit_88		269
+#define OBJ_id_pkix1_explicit_88		OBJ_id_pkix_mod,1L
+
+#define SN_id_pkix1_implicit_88		"id-pkix1-implicit-88"
+#define NID_id_pkix1_implicit_88		270
+#define OBJ_id_pkix1_implicit_88		OBJ_id_pkix_mod,2L
+
+#define SN_id_pkix1_explicit_93		"id-pkix1-explicit-93"
+#define NID_id_pkix1_explicit_93		271
+#define OBJ_id_pkix1_explicit_93		OBJ_id_pkix_mod,3L
+
+#define SN_id_pkix1_implicit_93		"id-pkix1-implicit-93"
+#define NID_id_pkix1_implicit_93		272
+#define OBJ_id_pkix1_implicit_93		OBJ_id_pkix_mod,4L
+
+#define SN_id_mod_crmf		"id-mod-crmf"
+#define NID_id_mod_crmf		273
+#define OBJ_id_mod_crmf		OBJ_id_pkix_mod,5L
+
+#define SN_id_mod_cmc		"id-mod-cmc"
+#define NID_id_mod_cmc		274
+#define OBJ_id_mod_cmc		OBJ_id_pkix_mod,6L
+
+#define SN_id_mod_kea_profile_88		"id-mod-kea-profile-88"
+#define NID_id_mod_kea_profile_88		275
+#define OBJ_id_mod_kea_profile_88		OBJ_id_pkix_mod,7L
+
+#define SN_id_mod_kea_profile_93		"id-mod-kea-profile-93"
+#define NID_id_mod_kea_profile_93		276
+#define OBJ_id_mod_kea_profile_93		OBJ_id_pkix_mod,8L
+
+#define SN_id_mod_cmp		"id-mod-cmp"
+#define NID_id_mod_cmp		277
+#define OBJ_id_mod_cmp		OBJ_id_pkix_mod,9L
+
+#define SN_id_mod_qualified_cert_88		"id-mod-qualified-cert-88"
+#define NID_id_mod_qualified_cert_88		278
+#define OBJ_id_mod_qualified_cert_88		OBJ_id_pkix_mod,10L
+
+#define SN_id_mod_qualified_cert_93		"id-mod-qualified-cert-93"
+#define NID_id_mod_qualified_cert_93		279
+#define OBJ_id_mod_qualified_cert_93		OBJ_id_pkix_mod,11L
+
+#define SN_id_mod_attribute_cert		"id-mod-attribute-cert"
+#define NID_id_mod_attribute_cert		280
+#define OBJ_id_mod_attribute_cert		OBJ_id_pkix_mod,12L
+
+#define SN_id_mod_timestamp_protocol		"id-mod-timestamp-protocol"
+#define NID_id_mod_timestamp_protocol		281
+#define OBJ_id_mod_timestamp_protocol		OBJ_id_pkix_mod,13L
+
+#define SN_id_mod_ocsp		"id-mod-ocsp"
+#define NID_id_mod_ocsp		282
+#define OBJ_id_mod_ocsp		OBJ_id_pkix_mod,14L
+
+#define SN_id_mod_dvcs		"id-mod-dvcs"
+#define NID_id_mod_dvcs		283
+#define OBJ_id_mod_dvcs		OBJ_id_pkix_mod,15L
+
+#define SN_id_mod_cmp2000		"id-mod-cmp2000"
+#define NID_id_mod_cmp2000		284
+#define OBJ_id_mod_cmp2000		OBJ_id_pkix_mod,16L
+
+#define SN_info_access		"authorityInfoAccess"
+#define LN_info_access		"Authority Information Access"
+#define NID_info_access		177
+#define OBJ_info_access		OBJ_id_pe,1L
+
+#define SN_biometricInfo		"biometricInfo"
+#define LN_biometricInfo		"Biometric Info"
+#define NID_biometricInfo		285
+#define OBJ_biometricInfo		OBJ_id_pe,2L
+
+#define SN_qcStatements		"qcStatements"
+#define NID_qcStatements		286
+#define OBJ_qcStatements		OBJ_id_pe,3L
+
+#define SN_ac_auditEntity		"ac-auditEntity"
+#define NID_ac_auditEntity		287
+#define OBJ_ac_auditEntity		OBJ_id_pe,4L
+
+#define SN_ac_targeting		"ac-targeting"
+#define NID_ac_targeting		288
+#define OBJ_ac_targeting		OBJ_id_pe,5L
+
+#define SN_aaControls		"aaControls"
+#define NID_aaControls		289
+#define OBJ_aaControls		OBJ_id_pe,6L
+
+#define SN_sbqp_ipAddrBlock		"sbqp-ipAddrBlock"
+#define NID_sbqp_ipAddrBlock		290
+#define OBJ_sbqp_ipAddrBlock		OBJ_id_pe,7L
+
+#define SN_sbqp_autonomousSysNum		"sbqp-autonomousSysNum"
+#define NID_sbqp_autonomousSysNum		291
+#define OBJ_sbqp_autonomousSysNum		OBJ_id_pe,8L
+
+#define SN_sbqp_routerIdentifier		"sbqp-routerIdentifier"
+#define NID_sbqp_routerIdentifier		292
+#define OBJ_sbqp_routerIdentifier		OBJ_id_pe,9L
+
+#define SN_ac_proxying		"ac-proxying"
+#define NID_ac_proxying		397
+#define OBJ_ac_proxying		OBJ_id_pe,10L
+
+#define SN_sinfo_access		"subjectInfoAccess"
+#define LN_sinfo_access		"Subject Information Access"
+#define NID_sinfo_access		398
+#define OBJ_sinfo_access		OBJ_id_pe,11L
+
+#define SN_proxyCertInfo		"proxyCertInfo"
+#define LN_proxyCertInfo		"Proxy Certificate Information"
+#define NID_proxyCertInfo		663
+#define OBJ_proxyCertInfo		OBJ_id_pe,14L
+
+#define SN_id_qt_cps		"id-qt-cps"
+#define LN_id_qt_cps		"Policy Qualifier CPS"
+#define NID_id_qt_cps		164
+#define OBJ_id_qt_cps		OBJ_id_qt,1L
+
+#define SN_id_qt_unotice		"id-qt-unotice"
+#define LN_id_qt_unotice		"Policy Qualifier User Notice"
+#define NID_id_qt_unotice		165
+#define OBJ_id_qt_unotice		OBJ_id_qt,2L
+
+#define SN_textNotice		"textNotice"
+#define NID_textNotice		293
+#define OBJ_textNotice		OBJ_id_qt,3L
+
+#define SN_server_auth		"serverAuth"
+#define LN_server_auth		"TLS Web Server Authentication"
+#define NID_server_auth		129
+#define OBJ_server_auth		OBJ_id_kp,1L
+
+#define SN_client_auth		"clientAuth"
+#define LN_client_auth		"TLS Web Client Authentication"
+#define NID_client_auth		130
+#define OBJ_client_auth		OBJ_id_kp,2L
+
+#define SN_code_sign		"codeSigning"
+#define LN_code_sign		"Code Signing"
+#define NID_code_sign		131
+#define OBJ_code_sign		OBJ_id_kp,3L
+
+#define SN_email_protect		"emailProtection"
+#define LN_email_protect		"E-mail Protection"
+#define NID_email_protect		132
+#define OBJ_email_protect		OBJ_id_kp,4L
+
+#define SN_ipsecEndSystem		"ipsecEndSystem"
+#define LN_ipsecEndSystem		"IPSec End System"
+#define NID_ipsecEndSystem		294
+#define OBJ_ipsecEndSystem		OBJ_id_kp,5L
+
+#define SN_ipsecTunnel		"ipsecTunnel"
+#define LN_ipsecTunnel		"IPSec Tunnel"
+#define NID_ipsecTunnel		295
+#define OBJ_ipsecTunnel		OBJ_id_kp,6L
+
+#define SN_ipsecUser		"ipsecUser"
+#define LN_ipsecUser		"IPSec User"
+#define NID_ipsecUser		296
+#define OBJ_ipsecUser		OBJ_id_kp,7L
+
+#define SN_time_stamp		"timeStamping"
+#define LN_time_stamp		"Time Stamping"
+#define NID_time_stamp		133
+#define OBJ_time_stamp		OBJ_id_kp,8L
+
+#define SN_OCSP_sign		"OCSPSigning"
+#define LN_OCSP_sign		"OCSP Signing"
+#define NID_OCSP_sign		180
+#define OBJ_OCSP_sign		OBJ_id_kp,9L
+
+#define SN_dvcs		"DVCS"
+#define LN_dvcs		"dvcs"
+#define NID_dvcs		297
+#define OBJ_dvcs		OBJ_id_kp,10L
+
+#define SN_id_it_caProtEncCert		"id-it-caProtEncCert"
+#define NID_id_it_caProtEncCert		298
+#define OBJ_id_it_caProtEncCert		OBJ_id_it,1L
+
+#define SN_id_it_signKeyPairTypes		"id-it-signKeyPairTypes"
+#define NID_id_it_signKeyPairTypes		299
+#define OBJ_id_it_signKeyPairTypes		OBJ_id_it,2L
+
+#define SN_id_it_encKeyPairTypes		"id-it-encKeyPairTypes"
+#define NID_id_it_encKeyPairTypes		300
+#define OBJ_id_it_encKeyPairTypes		OBJ_id_it,3L
+
+#define SN_id_it_preferredSymmAlg		"id-it-preferredSymmAlg"
+#define NID_id_it_preferredSymmAlg		301
+#define OBJ_id_it_preferredSymmAlg		OBJ_id_it,4L
+
+#define SN_id_it_caKeyUpdateInfo		"id-it-caKeyUpdateInfo"
+#define NID_id_it_caKeyUpdateInfo		302
+#define OBJ_id_it_caKeyUpdateInfo		OBJ_id_it,5L
+
+#define SN_id_it_currentCRL		"id-it-currentCRL"
+#define NID_id_it_currentCRL		303
+#define OBJ_id_it_currentCRL		OBJ_id_it,6L
+
+#define SN_id_it_unsupportedOIDs		"id-it-unsupportedOIDs"
+#define NID_id_it_unsupportedOIDs		304
+#define OBJ_id_it_unsupportedOIDs		OBJ_id_it,7L
+
+#define SN_id_it_subscriptionRequest		"id-it-subscriptionRequest"
+#define NID_id_it_subscriptionRequest		305
+#define OBJ_id_it_subscriptionRequest		OBJ_id_it,8L
+
+#define SN_id_it_subscriptionResponse		"id-it-subscriptionResponse"
+#define NID_id_it_subscriptionResponse		306
+#define OBJ_id_it_subscriptionResponse		OBJ_id_it,9L
+
+#define SN_id_it_keyPairParamReq		"id-it-keyPairParamReq"
+#define NID_id_it_keyPairParamReq		307
+#define OBJ_id_it_keyPairParamReq		OBJ_id_it,10L
+
+#define SN_id_it_keyPairParamRep		"id-it-keyPairParamRep"
+#define NID_id_it_keyPairParamRep		308
+#define OBJ_id_it_keyPairParamRep		OBJ_id_it,11L
+
+#define SN_id_it_revPassphrase		"id-it-revPassphrase"
+#define NID_id_it_revPassphrase		309
+#define OBJ_id_it_revPassphrase		OBJ_id_it,12L
+
+#define SN_id_it_implicitConfirm		"id-it-implicitConfirm"
+#define NID_id_it_implicitConfirm		310
+#define OBJ_id_it_implicitConfirm		OBJ_id_it,13L
+
+#define SN_id_it_confirmWaitTime		"id-it-confirmWaitTime"
+#define NID_id_it_confirmWaitTime		311
+#define OBJ_id_it_confirmWaitTime		OBJ_id_it,14L
+
+#define SN_id_it_origPKIMessage		"id-it-origPKIMessage"
+#define NID_id_it_origPKIMessage		312
+#define OBJ_id_it_origPKIMessage		OBJ_id_it,15L
+
+#define SN_id_regCtrl		"id-regCtrl"
+#define NID_id_regCtrl		313
+#define OBJ_id_regCtrl		OBJ_id_pkip,1L
+
+#define SN_id_regInfo		"id-regInfo"
+#define NID_id_regInfo		314
+#define OBJ_id_regInfo		OBJ_id_pkip,2L
+
+#define SN_id_regCtrl_regToken		"id-regCtrl-regToken"
+#define NID_id_regCtrl_regToken		315
+#define OBJ_id_regCtrl_regToken		OBJ_id_regCtrl,1L
+
+#define SN_id_regCtrl_authenticator		"id-regCtrl-authenticator"
+#define NID_id_regCtrl_authenticator		316
+#define OBJ_id_regCtrl_authenticator		OBJ_id_regCtrl,2L
+
+#define SN_id_regCtrl_pkiPublicationInfo		"id-regCtrl-pkiPublicationInfo"
+#define NID_id_regCtrl_pkiPublicationInfo		317
+#define OBJ_id_regCtrl_pkiPublicationInfo		OBJ_id_regCtrl,3L
+
+#define SN_id_regCtrl_pkiArchiveOptions		"id-regCtrl-pkiArchiveOptions"
+#define NID_id_regCtrl_pkiArchiveOptions		318
+#define OBJ_id_regCtrl_pkiArchiveOptions		OBJ_id_regCtrl,4L
+
+#define SN_id_regCtrl_oldCertID		"id-regCtrl-oldCertID"
+#define NID_id_regCtrl_oldCertID		319
+#define OBJ_id_regCtrl_oldCertID		OBJ_id_regCtrl,5L
+
+#define SN_id_regCtrl_protocolEncrKey		"id-regCtrl-protocolEncrKey"
+#define NID_id_regCtrl_protocolEncrKey		320
+#define OBJ_id_regCtrl_protocolEncrKey		OBJ_id_regCtrl,6L
+
+#define SN_id_regInfo_utf8Pairs		"id-regInfo-utf8Pairs"
+#define NID_id_regInfo_utf8Pairs		321
+#define OBJ_id_regInfo_utf8Pairs		OBJ_id_regInfo,1L
+
+#define SN_id_regInfo_certReq		"id-regInfo-certReq"
+#define NID_id_regInfo_certReq		322
+#define OBJ_id_regInfo_certReq		OBJ_id_regInfo,2L
+
+#define SN_id_alg_des40		"id-alg-des40"
+#define NID_id_alg_des40		323
+#define OBJ_id_alg_des40		OBJ_id_alg,1L
+
+#define SN_id_alg_noSignature		"id-alg-noSignature"
+#define NID_id_alg_noSignature		324
+#define OBJ_id_alg_noSignature		OBJ_id_alg,2L
+
+#define SN_id_alg_dh_sig_hmac_sha1		"id-alg-dh-sig-hmac-sha1"
+#define NID_id_alg_dh_sig_hmac_sha1		325
+#define OBJ_id_alg_dh_sig_hmac_sha1		OBJ_id_alg,3L
+
+#define SN_id_alg_dh_pop		"id-alg-dh-pop"
+#define NID_id_alg_dh_pop		326
+#define OBJ_id_alg_dh_pop		OBJ_id_alg,4L
+
+#define SN_id_cmc_statusInfo		"id-cmc-statusInfo"
+#define NID_id_cmc_statusInfo		327
+#define OBJ_id_cmc_statusInfo		OBJ_id_cmc,1L
+
+#define SN_id_cmc_identification		"id-cmc-identification"
+#define NID_id_cmc_identification		328
+#define OBJ_id_cmc_identification		OBJ_id_cmc,2L
+
+#define SN_id_cmc_identityProof		"id-cmc-identityProof"
+#define NID_id_cmc_identityProof		329
+#define OBJ_id_cmc_identityProof		OBJ_id_cmc,3L
+
+#define SN_id_cmc_dataReturn		"id-cmc-dataReturn"
+#define NID_id_cmc_dataReturn		330
+#define OBJ_id_cmc_dataReturn		OBJ_id_cmc,4L
+
+#define SN_id_cmc_transactionId		"id-cmc-transactionId"
+#define NID_id_cmc_transactionId		331
+#define OBJ_id_cmc_transactionId		OBJ_id_cmc,5L
+
+#define SN_id_cmc_senderNonce		"id-cmc-senderNonce"
+#define NID_id_cmc_senderNonce		332
+#define OBJ_id_cmc_senderNonce		OBJ_id_cmc,6L
+
+#define SN_id_cmc_recipientNonce		"id-cmc-recipientNonce"
+#define NID_id_cmc_recipientNonce		333
+#define OBJ_id_cmc_recipientNonce		OBJ_id_cmc,7L
+
+#define SN_id_cmc_addExtensions		"id-cmc-addExtensions"
+#define NID_id_cmc_addExtensions		334
+#define OBJ_id_cmc_addExtensions		OBJ_id_cmc,8L
+
+#define SN_id_cmc_encryptedPOP		"id-cmc-encryptedPOP"
+#define NID_id_cmc_encryptedPOP		335
+#define OBJ_id_cmc_encryptedPOP		OBJ_id_cmc,9L
+
+#define SN_id_cmc_decryptedPOP		"id-cmc-decryptedPOP"
+#define NID_id_cmc_decryptedPOP		336
+#define OBJ_id_cmc_decryptedPOP		OBJ_id_cmc,10L
+
+#define SN_id_cmc_lraPOPWitness		"id-cmc-lraPOPWitness"
+#define NID_id_cmc_lraPOPWitness		337
+#define OBJ_id_cmc_lraPOPWitness		OBJ_id_cmc,11L
+
+#define SN_id_cmc_getCert		"id-cmc-getCert"
+#define NID_id_cmc_getCert		338
+#define OBJ_id_cmc_getCert		OBJ_id_cmc,15L
+
+#define SN_id_cmc_getCRL		"id-cmc-getCRL"
+#define NID_id_cmc_getCRL		339
+#define OBJ_id_cmc_getCRL		OBJ_id_cmc,16L
+
+#define SN_id_cmc_revokeRequest		"id-cmc-revokeRequest"
+#define NID_id_cmc_revokeRequest		340
+#define OBJ_id_cmc_revokeRequest		OBJ_id_cmc,17L
+
+#define SN_id_cmc_regInfo		"id-cmc-regInfo"
+#define NID_id_cmc_regInfo		341
+#define OBJ_id_cmc_regInfo		OBJ_id_cmc,18L
+
+#define SN_id_cmc_responseInfo		"id-cmc-responseInfo"
+#define NID_id_cmc_responseInfo		342
+#define OBJ_id_cmc_responseInfo		OBJ_id_cmc,19L
+
+#define SN_id_cmc_queryPending		"id-cmc-queryPending"
+#define NID_id_cmc_queryPending		343
+#define OBJ_id_cmc_queryPending		OBJ_id_cmc,21L
+
+#define SN_id_cmc_popLinkRandom		"id-cmc-popLinkRandom"
+#define NID_id_cmc_popLinkRandom		344
+#define OBJ_id_cmc_popLinkRandom		OBJ_id_cmc,22L
+
+#define SN_id_cmc_popLinkWitness		"id-cmc-popLinkWitness"
+#define NID_id_cmc_popLinkWitness		345
+#define OBJ_id_cmc_popLinkWitness		OBJ_id_cmc,23L
+
+#define SN_id_cmc_confirmCertAcceptance		"id-cmc-confirmCertAcceptance"
+#define NID_id_cmc_confirmCertAcceptance		346
+#define OBJ_id_cmc_confirmCertAcceptance		OBJ_id_cmc,24L
+
+#define SN_id_on_personalData		"id-on-personalData"
+#define NID_id_on_personalData		347
+#define OBJ_id_on_personalData		OBJ_id_on,1L
+
+#define SN_id_pda_dateOfBirth		"id-pda-dateOfBirth"
+#define NID_id_pda_dateOfBirth		348
+#define OBJ_id_pda_dateOfBirth		OBJ_id_pda,1L
+
+#define SN_id_pda_placeOfBirth		"id-pda-placeOfBirth"
+#define NID_id_pda_placeOfBirth		349
+#define OBJ_id_pda_placeOfBirth		OBJ_id_pda,2L
+
+#define SN_id_pda_gender		"id-pda-gender"
+#define NID_id_pda_gender		351
+#define OBJ_id_pda_gender		OBJ_id_pda,3L
+
+#define SN_id_pda_countryOfCitizenship		"id-pda-countryOfCitizenship"
+#define NID_id_pda_countryOfCitizenship		352
+#define OBJ_id_pda_countryOfCitizenship		OBJ_id_pda,4L
+
+#define SN_id_pda_countryOfResidence		"id-pda-countryOfResidence"
+#define NID_id_pda_countryOfResidence		353
+#define OBJ_id_pda_countryOfResidence		OBJ_id_pda,5L
+
+#define SN_id_aca_authenticationInfo		"id-aca-authenticationInfo"
+#define NID_id_aca_authenticationInfo		354
+#define OBJ_id_aca_authenticationInfo		OBJ_id_aca,1L
+
+#define SN_id_aca_accessIdentity		"id-aca-accessIdentity"
+#define NID_id_aca_accessIdentity		355
+#define OBJ_id_aca_accessIdentity		OBJ_id_aca,2L
+
+#define SN_id_aca_chargingIdentity		"id-aca-chargingIdentity"
+#define NID_id_aca_chargingIdentity		356
+#define OBJ_id_aca_chargingIdentity		OBJ_id_aca,3L
+
+#define SN_id_aca_group		"id-aca-group"
+#define NID_id_aca_group		357
+#define OBJ_id_aca_group		OBJ_id_aca,4L
+
+#define SN_id_aca_role		"id-aca-role"
+#define NID_id_aca_role		358
+#define OBJ_id_aca_role		OBJ_id_aca,5L
+
+#define SN_id_aca_encAttrs		"id-aca-encAttrs"
+#define NID_id_aca_encAttrs		399
+#define OBJ_id_aca_encAttrs		OBJ_id_aca,6L
+
+#define SN_id_qcs_pkixQCSyntax_v1		"id-qcs-pkixQCSyntax-v1"
+#define NID_id_qcs_pkixQCSyntax_v1		359
+#define OBJ_id_qcs_pkixQCSyntax_v1		OBJ_id_qcs,1L
+
+#define SN_id_cct_crs		"id-cct-crs"
+#define NID_id_cct_crs		360
+#define OBJ_id_cct_crs		OBJ_id_cct,1L
+
+#define SN_id_cct_PKIData		"id-cct-PKIData"
+#define NID_id_cct_PKIData		361
+#define OBJ_id_cct_PKIData		OBJ_id_cct,2L
+
+#define SN_id_cct_PKIResponse		"id-cct-PKIResponse"
+#define NID_id_cct_PKIResponse		362
+#define OBJ_id_cct_PKIResponse		OBJ_id_cct,3L
+
+#define SN_id_ppl_anyLanguage		"id-ppl-anyLanguage"
+#define LN_id_ppl_anyLanguage		"Any language"
+#define NID_id_ppl_anyLanguage		664
+#define OBJ_id_ppl_anyLanguage		OBJ_id_ppl,0L
+
+#define SN_id_ppl_inheritAll		"id-ppl-inheritAll"
+#define LN_id_ppl_inheritAll		"Inherit all"
+#define NID_id_ppl_inheritAll		665
+#define OBJ_id_ppl_inheritAll		OBJ_id_ppl,1L
+
+#define SN_Independent		"id-ppl-independent"
+#define LN_Independent		"Independent"
+#define NID_Independent		667
+#define OBJ_Independent		OBJ_id_ppl,2L
+
+#define SN_ad_OCSP		"OCSP"
+#define LN_ad_OCSP		"OCSP"
+#define NID_ad_OCSP		178
+#define OBJ_ad_OCSP		OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers		"caIssuers"
+#define LN_ad_ca_issuers		"CA Issuers"
+#define NID_ad_ca_issuers		179
+#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
+
+#define SN_ad_timeStamping		"ad_timestamping"
+#define LN_ad_timeStamping		"AD Time Stamping"
+#define NID_ad_timeStamping		363
+#define OBJ_ad_timeStamping		OBJ_id_ad,3L
+
+#define SN_ad_dvcs		"AD_DVCS"
+#define LN_ad_dvcs		"ad dvcs"
+#define NID_ad_dvcs		364
+#define OBJ_ad_dvcs		OBJ_id_ad,4L
+
+#define OBJ_id_pkix_OCSP		OBJ_ad_OCSP
+
+#define SN_id_pkix_OCSP_basic		"basicOCSPResponse"
+#define LN_id_pkix_OCSP_basic		"Basic OCSP Response"
+#define NID_id_pkix_OCSP_basic		365
+#define OBJ_id_pkix_OCSP_basic		OBJ_id_pkix_OCSP,1L
+
+#define SN_id_pkix_OCSP_Nonce		"Nonce"
+#define LN_id_pkix_OCSP_Nonce		"OCSP Nonce"
+#define NID_id_pkix_OCSP_Nonce		366
+#define OBJ_id_pkix_OCSP_Nonce		OBJ_id_pkix_OCSP,2L
+
+#define SN_id_pkix_OCSP_CrlID		"CrlID"
+#define LN_id_pkix_OCSP_CrlID		"OCSP CRL ID"
+#define NID_id_pkix_OCSP_CrlID		367
+#define OBJ_id_pkix_OCSP_CrlID		OBJ_id_pkix_OCSP,3L
+
+#define SN_id_pkix_OCSP_acceptableResponses		"acceptableResponses"
+#define LN_id_pkix_OCSP_acceptableResponses		"Acceptable OCSP Responses"
+#define NID_id_pkix_OCSP_acceptableResponses		368
+#define OBJ_id_pkix_OCSP_acceptableResponses		OBJ_id_pkix_OCSP,4L
+
+#define SN_id_pkix_OCSP_noCheck		"noCheck"
+#define LN_id_pkix_OCSP_noCheck		"OCSP No Check"
+#define NID_id_pkix_OCSP_noCheck		369
+#define OBJ_id_pkix_OCSP_noCheck		OBJ_id_pkix_OCSP,5L
+
+#define SN_id_pkix_OCSP_archiveCutoff		"archiveCutoff"
+#define LN_id_pkix_OCSP_archiveCutoff		"OCSP Archive Cutoff"
+#define NID_id_pkix_OCSP_archiveCutoff		370
+#define OBJ_id_pkix_OCSP_archiveCutoff		OBJ_id_pkix_OCSP,6L
+
+#define SN_id_pkix_OCSP_serviceLocator		"serviceLocator"
+#define LN_id_pkix_OCSP_serviceLocator		"OCSP Service Locator"
+#define NID_id_pkix_OCSP_serviceLocator		371
+#define OBJ_id_pkix_OCSP_serviceLocator		OBJ_id_pkix_OCSP,7L
+
+#define SN_id_pkix_OCSP_extendedStatus		"extendedStatus"
+#define LN_id_pkix_OCSP_extendedStatus		"Extended OCSP Status"
+#define NID_id_pkix_OCSP_extendedStatus		372
+#define OBJ_id_pkix_OCSP_extendedStatus		OBJ_id_pkix_OCSP,8L
+
+#define SN_id_pkix_OCSP_valid		"valid"
+#define NID_id_pkix_OCSP_valid		373
+#define OBJ_id_pkix_OCSP_valid		OBJ_id_pkix_OCSP,9L
+
+#define SN_id_pkix_OCSP_path		"path"
+#define NID_id_pkix_OCSP_path		374
+#define OBJ_id_pkix_OCSP_path		OBJ_id_pkix_OCSP,10L
+
+#define SN_id_pkix_OCSP_trustRoot		"trustRoot"
+#define LN_id_pkix_OCSP_trustRoot		"Trust Root"
+#define NID_id_pkix_OCSP_trustRoot		375
+#define OBJ_id_pkix_OCSP_trustRoot		OBJ_id_pkix_OCSP,11L
+
+#define SN_algorithm		"algorithm"
+#define LN_algorithm		"algorithm"
+#define NID_algorithm		376
+#define OBJ_algorithm		1L,3L,14L,3L,2L
+
+#define SN_md5WithRSA		"RSA-NP-MD5"
+#define LN_md5WithRSA		"md5WithRSA"
+#define NID_md5WithRSA		104
+#define OBJ_md5WithRSA		OBJ_algorithm,3L
+
+#define SN_des_ecb		"DES-ECB"
+#define LN_des_ecb		"des-ecb"
+#define NID_des_ecb		29
+#define OBJ_des_ecb		OBJ_algorithm,6L
+
+#define SN_des_cbc		"DES-CBC"
+#define LN_des_cbc		"des-cbc"
+#define NID_des_cbc		31
+#define OBJ_des_cbc		OBJ_algorithm,7L
+
+#define SN_des_ofb64		"DES-OFB"
+#define LN_des_ofb64		"des-ofb"
+#define NID_des_ofb64		45
+#define OBJ_des_ofb64		OBJ_algorithm,8L
+
+#define SN_des_cfb64		"DES-CFB"
+#define LN_des_cfb64		"des-cfb"
+#define NID_des_cfb64		30
+#define OBJ_des_cfb64		OBJ_algorithm,9L
+
+#define SN_rsaSignature		"rsaSignature"
+#define NID_rsaSignature		377
+#define OBJ_rsaSignature		OBJ_algorithm,11L
+
+#define SN_dsa_2		"DSA-old"
+#define LN_dsa_2		"dsaEncryption-old"
+#define NID_dsa_2		67
+#define OBJ_dsa_2		OBJ_algorithm,12L
+
+#define SN_dsaWithSHA		"DSA-SHA"
+#define LN_dsaWithSHA		"dsaWithSHA"
+#define NID_dsaWithSHA		66
+#define OBJ_dsaWithSHA		OBJ_algorithm,13L
+
+#define SN_shaWithRSAEncryption		"RSA-SHA"
+#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption		42
+#define OBJ_shaWithRSAEncryption		OBJ_algorithm,15L
+
+#define SN_des_ede_ecb		"DES-EDE"
+#define LN_des_ede_ecb		"des-ede"
+#define NID_des_ede_ecb		32
+#define OBJ_des_ede_ecb		OBJ_algorithm,17L
+
+#define SN_des_ede3_ecb		"DES-EDE3"
+#define LN_des_ede3_ecb		"des-ede3"
+#define NID_des_ede3_ecb		33
+
+#define SN_des_ede_cbc		"DES-EDE-CBC"
+#define LN_des_ede_cbc		"des-ede-cbc"
+#define NID_des_ede_cbc		43
+
+#define SN_des_ede_cfb64		"DES-EDE-CFB"
+#define LN_des_ede_cfb64		"des-ede-cfb"
+#define NID_des_ede_cfb64		60
+
+#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
+#define LN_des_ede3_cfb64		"des-ede3-cfb"
+#define NID_des_ede3_cfb64		61
+
+#define SN_des_ede_ofb64		"DES-EDE-OFB"
+#define LN_des_ede_ofb64		"des-ede-ofb"
+#define NID_des_ede_ofb64		62
+
+#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
+#define LN_des_ede3_ofb64		"des-ede3-ofb"
+#define NID_des_ede3_ofb64		63
+
+#define SN_desx_cbc		"DESX-CBC"
+#define LN_desx_cbc		"desx-cbc"
+#define NID_desx_cbc		80
+
+#define SN_sha		"SHA"
+#define LN_sha		"sha"
+#define NID_sha		41
+#define OBJ_sha		OBJ_algorithm,18L
+
+#define SN_sha1		"SHA1"
+#define LN_sha1		"sha1"
+#define NID_sha1		64
+#define OBJ_sha1		OBJ_algorithm,26L
+
+#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
+#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2		70
+#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
+
+#define SN_sha1WithRSA		"RSA-SHA1-2"
+#define LN_sha1WithRSA		"sha1WithRSA"
+#define NID_sha1WithRSA		115
+#define OBJ_sha1WithRSA		OBJ_algorithm,29L
+
+#define SN_ripemd160		"RIPEMD160"
+#define LN_ripemd160		"ripemd160"
+#define NID_ripemd160		117
+#define OBJ_ripemd160		1L,3L,36L,3L,2L,1L
+
+#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
+#define LN_ripemd160WithRSA		"ripemd160WithRSA"
+#define NID_ripemd160WithRSA		119
+#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
+
+#define SN_sxnet		"SXNetID"
+#define LN_sxnet		"Strong Extranet ID"
+#define NID_sxnet		143
+#define OBJ_sxnet		1L,3L,101L,1L,4L,1L
+
+#define SN_X500		"X500"
+#define LN_X500		"directory services (X.500)"
+#define NID_X500		11
+#define OBJ_X500		2L,5L
+
+#define SN_X509		"X509"
+#define NID_X509		12
+#define OBJ_X509		OBJ_X500,4L
+
+#define SN_commonName		"CN"
+#define LN_commonName		"commonName"
+#define NID_commonName		13
+#define OBJ_commonName		OBJ_X509,3L
+
+#define SN_surname		"SN"
+#define LN_surname		"surname"
+#define NID_surname		100
+#define OBJ_surname		OBJ_X509,4L
+
+#define LN_serialNumber		"serialNumber"
+#define NID_serialNumber		105
+#define OBJ_serialNumber		OBJ_X509,5L
+
+#define SN_countryName		"C"
+#define LN_countryName		"countryName"
+#define NID_countryName		14
+#define OBJ_countryName		OBJ_X509,6L
+
+#define SN_localityName		"L"
+#define LN_localityName		"localityName"
+#define NID_localityName		15
+#define OBJ_localityName		OBJ_X509,7L
+
+#define SN_stateOrProvinceName		"ST"
+#define LN_stateOrProvinceName		"stateOrProvinceName"
+#define NID_stateOrProvinceName		16
+#define OBJ_stateOrProvinceName		OBJ_X509,8L
+
+#define LN_streetAddress		"streetAddress"
+#define NID_streetAddress		660
+#define OBJ_streetAddress		OBJ_X509,9L
+
+#define SN_organizationName		"O"
+#define LN_organizationName		"organizationName"
+#define NID_organizationName		17
+#define OBJ_organizationName		OBJ_X509,10L
+
+#define SN_organizationalUnitName		"OU"
+#define LN_organizationalUnitName		"organizationalUnitName"
+#define NID_organizationalUnitName		18
+#define OBJ_organizationalUnitName		OBJ_X509,11L
+
+#define LN_title		"title"
+#define NID_title		106
+#define OBJ_title		OBJ_X509,12L
+
+#define LN_description		"description"
+#define NID_description		107
+#define OBJ_description		OBJ_X509,13L
+
+#define LN_postalCode		"postalCode"
+#define NID_postalCode		661
+#define OBJ_postalCode		OBJ_X509,17L
+
+#define SN_name		"name"
+#define LN_name		"name"
+#define NID_name		173
+#define OBJ_name		OBJ_X509,41L
+
+#define SN_givenName		"GN"
+#define LN_givenName		"givenName"
+#define NID_givenName		99
+#define OBJ_givenName		OBJ_X509,42L
+
+#define LN_initials		"initials"
+#define NID_initials		101
+#define OBJ_initials		OBJ_X509,43L
+
+#define LN_generationQualifier		"generationQualifier"
+#define NID_generationQualifier		509
+#define OBJ_generationQualifier		OBJ_X509,44L
+
+#define LN_x500UniqueIdentifier		"x500UniqueIdentifier"
+#define NID_x500UniqueIdentifier		503
+#define OBJ_x500UniqueIdentifier		OBJ_X509,45L
+
+#define SN_dnQualifier		"dnQualifier"
+#define LN_dnQualifier		"dnQualifier"
+#define NID_dnQualifier		174
+#define OBJ_dnQualifier		OBJ_X509,46L
+
+#define LN_pseudonym		"pseudonym"
+#define NID_pseudonym		510
+#define OBJ_pseudonym		OBJ_X509,65L
+
+#define SN_role		"role"
+#define LN_role		"role"
+#define NID_role		400
+#define OBJ_role		OBJ_X509,72L
+
+#define SN_X500algorithms		"X500algorithms"
+#define LN_X500algorithms		"directory services - algorithms"
+#define NID_X500algorithms		378
+#define OBJ_X500algorithms		OBJ_X500,8L
+
+#define SN_rsa		"RSA"
+#define LN_rsa		"rsa"
+#define NID_rsa		19
+#define OBJ_rsa		OBJ_X500algorithms,1L,1L
+
+#define SN_mdc2WithRSA		"RSA-MDC2"
+#define LN_mdc2WithRSA		"mdc2WithRSA"
+#define NID_mdc2WithRSA		96
+#define OBJ_mdc2WithRSA		OBJ_X500algorithms,3L,100L
+
+#define SN_mdc2		"MDC2"
+#define LN_mdc2		"mdc2"
+#define NID_mdc2		95
+#define OBJ_mdc2		OBJ_X500algorithms,3L,101L
+
+#define SN_id_ce		"id-ce"
+#define NID_id_ce		81
+#define OBJ_id_ce		OBJ_X500,29L
+
+#define SN_subject_key_identifier		"subjectKeyIdentifier"
+#define LN_subject_key_identifier		"X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier		82
+#define OBJ_subject_key_identifier		OBJ_id_ce,14L
+
+#define SN_key_usage		"keyUsage"
+#define LN_key_usage		"X509v3 Key Usage"
+#define NID_key_usage		83
+#define OBJ_key_usage		OBJ_id_ce,15L
+
+#define SN_private_key_usage_period		"privateKeyUsagePeriod"
+#define LN_private_key_usage_period		"X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period		84
+#define OBJ_private_key_usage_period		OBJ_id_ce,16L
+
+#define SN_subject_alt_name		"subjectAltName"
+#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
+#define NID_subject_alt_name		85
+#define OBJ_subject_alt_name		OBJ_id_ce,17L
+
+#define SN_issuer_alt_name		"issuerAltName"
+#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name		86
+#define OBJ_issuer_alt_name		OBJ_id_ce,18L
+
+#define SN_basic_constraints		"basicConstraints"
+#define LN_basic_constraints		"X509v3 Basic Constraints"
+#define NID_basic_constraints		87
+#define OBJ_basic_constraints		OBJ_id_ce,19L
+
+#define SN_crl_number		"crlNumber"
+#define LN_crl_number		"X509v3 CRL Number"
+#define NID_crl_number		88
+#define OBJ_crl_number		OBJ_id_ce,20L
+
+#define SN_crl_reason		"CRLReason"
+#define LN_crl_reason		"X509v3 CRL Reason Code"
+#define NID_crl_reason		141
+#define OBJ_crl_reason		OBJ_id_ce,21L
+
+#define SN_invalidity_date		"invalidityDate"
+#define LN_invalidity_date		"Invalidity Date"
+#define NID_invalidity_date		142
+#define OBJ_invalidity_date		OBJ_id_ce,24L
+
+#define SN_delta_crl		"deltaCRL"
+#define LN_delta_crl		"X509v3 Delta CRL Indicator"
+#define NID_delta_crl		140
+#define OBJ_delta_crl		OBJ_id_ce,27L
+
+#define SN_name_constraints		"nameConstraints"
+#define LN_name_constraints		"X509v3 Name Constraints"
+#define NID_name_constraints		666
+#define OBJ_name_constraints		OBJ_id_ce,30L
+
+#define SN_crl_distribution_points		"crlDistributionPoints"
+#define LN_crl_distribution_points		"X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points		103
+#define OBJ_crl_distribution_points		OBJ_id_ce,31L
+
+#define SN_certificate_policies		"certificatePolicies"
+#define LN_certificate_policies		"X509v3 Certificate Policies"
+#define NID_certificate_policies		89
+#define OBJ_certificate_policies		OBJ_id_ce,32L
+
+#define SN_any_policy		"anyPolicy"
+#define LN_any_policy		"X509v3 Any Policy"
+#define NID_any_policy		746
+#define OBJ_any_policy		OBJ_certificate_policies,0L
+
+#define SN_policy_mappings		"policyMappings"
+#define LN_policy_mappings		"X509v3 Policy Mappings"
+#define NID_policy_mappings		747
+#define OBJ_policy_mappings		OBJ_id_ce,33L
+
+#define SN_authority_key_identifier		"authorityKeyIdentifier"
+#define LN_authority_key_identifier		"X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier		90
+#define OBJ_authority_key_identifier		OBJ_id_ce,35L
+
+#define SN_policy_constraints		"policyConstraints"
+#define LN_policy_constraints		"X509v3 Policy Constraints"
+#define NID_policy_constraints		401
+#define OBJ_policy_constraints		OBJ_id_ce,36L
+
+#define SN_ext_key_usage		"extendedKeyUsage"
+#define LN_ext_key_usage		"X509v3 Extended Key Usage"
+#define NID_ext_key_usage		126
+#define OBJ_ext_key_usage		OBJ_id_ce,37L
+
+#define SN_inhibit_any_policy		"inhibitAnyPolicy"
+#define LN_inhibit_any_policy		"X509v3 Inhibit Any Policy"
+#define NID_inhibit_any_policy		748
+#define OBJ_inhibit_any_policy		OBJ_id_ce,54L
+
+#define SN_target_information		"targetInformation"
+#define LN_target_information		"X509v3 AC Targeting"
+#define NID_target_information		402
+#define OBJ_target_information		OBJ_id_ce,55L
+
+#define SN_no_rev_avail		"noRevAvail"
+#define LN_no_rev_avail		"X509v3 No Revocation Available"
+#define NID_no_rev_avail		403
+#define OBJ_no_rev_avail		OBJ_id_ce,56L
+
+#define SN_netscape		"Netscape"
+#define LN_netscape		"Netscape Communications Corp."
+#define NID_netscape		57
+#define OBJ_netscape		2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension		"nsCertExt"
+#define LN_netscape_cert_extension		"Netscape Certificate Extension"
+#define NID_netscape_cert_extension		58
+#define OBJ_netscape_cert_extension		OBJ_netscape,1L
+
+#define SN_netscape_data_type		"nsDataType"
+#define LN_netscape_data_type		"Netscape Data Type"
+#define NID_netscape_data_type		59
+#define OBJ_netscape_data_type		OBJ_netscape,2L
+
+#define SN_netscape_cert_type		"nsCertType"
+#define LN_netscape_cert_type		"Netscape Cert Type"
+#define NID_netscape_cert_type		71
+#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url		"nsBaseUrl"
+#define LN_netscape_base_url		"Netscape Base Url"
+#define NID_netscape_base_url		72
+#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url		"nsRevocationUrl"
+#define LN_netscape_revocation_url		"Netscape Revocation Url"
+#define NID_netscape_revocation_url		73
+#define OBJ_netscape_revocation_url		OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url		"nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url		"Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url		74
+#define OBJ_netscape_ca_revocation_url		OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url		"nsRenewalUrl"
+#define LN_netscape_renewal_url		"Netscape Renewal Url"
+#define NID_netscape_renewal_url		75
+#define OBJ_netscape_renewal_url		OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url		"nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url		"Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url		76
+#define OBJ_netscape_ca_policy_url		OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name		"nsSslServerName"
+#define LN_netscape_ssl_server_name		"Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name		77
+#define OBJ_netscape_ssl_server_name		OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment		"nsComment"
+#define LN_netscape_comment		"Netscape Comment"
+#define NID_netscape_comment		78
+#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence		"nsCertSequence"
+#define LN_netscape_cert_sequence		"Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence		79
+#define OBJ_netscape_cert_sequence		OBJ_netscape_data_type,5L
+
+#define SN_ns_sgc		"nsSGC"
+#define LN_ns_sgc		"Netscape Server Gated Crypto"
+#define NID_ns_sgc		139
+#define OBJ_ns_sgc		OBJ_netscape,4L,1L
+
+#define SN_org		"ORG"
+#define LN_org		"org"
+#define NID_org		379
+#define OBJ_org		OBJ_iso,3L
+
+#define SN_dod		"DOD"
+#define LN_dod		"dod"
+#define NID_dod		380
+#define OBJ_dod		OBJ_org,6L
+
+#define SN_iana		"IANA"
+#define LN_iana		"iana"
+#define NID_iana		381
+#define OBJ_iana		OBJ_dod,1L
+
+#define OBJ_internet		OBJ_iana
+
+#define SN_Directory		"directory"
+#define LN_Directory		"Directory"
+#define NID_Directory		382
+#define OBJ_Directory		OBJ_internet,1L
+
+#define SN_Management		"mgmt"
+#define LN_Management		"Management"
+#define NID_Management		383
+#define OBJ_Management		OBJ_internet,2L
+
+#define SN_Experimental		"experimental"
+#define LN_Experimental		"Experimental"
+#define NID_Experimental		384
+#define OBJ_Experimental		OBJ_internet,3L
+
+#define SN_Private		"private"
+#define LN_Private		"Private"
+#define NID_Private		385
+#define OBJ_Private		OBJ_internet,4L
+
+#define SN_Security		"security"
+#define LN_Security		"Security"
+#define NID_Security		386
+#define OBJ_Security		OBJ_internet,5L
+
+#define SN_SNMPv2		"snmpv2"
+#define LN_SNMPv2		"SNMPv2"
+#define NID_SNMPv2		387
+#define OBJ_SNMPv2		OBJ_internet,6L
+
+#define LN_Mail		"Mail"
+#define NID_Mail		388
+#define OBJ_Mail		OBJ_internet,7L
+
+#define SN_Enterprises		"enterprises"
+#define LN_Enterprises		"Enterprises"
+#define NID_Enterprises		389
+#define OBJ_Enterprises		OBJ_Private,1L
+
+#define SN_dcObject		"dcobject"
+#define LN_dcObject		"dcObject"
+#define NID_dcObject		390
+#define OBJ_dcObject		OBJ_Enterprises,1466L,344L
+
+#define SN_mime_mhs		"mime-mhs"
+#define LN_mime_mhs		"MIME MHS"
+#define NID_mime_mhs		504
+#define OBJ_mime_mhs		OBJ_Mail,1L
+
+#define SN_mime_mhs_headings		"mime-mhs-headings"
+#define LN_mime_mhs_headings		"mime-mhs-headings"
+#define NID_mime_mhs_headings		505
+#define OBJ_mime_mhs_headings		OBJ_mime_mhs,1L
+
+#define SN_mime_mhs_bodies		"mime-mhs-bodies"
+#define LN_mime_mhs_bodies		"mime-mhs-bodies"
+#define NID_mime_mhs_bodies		506
+#define OBJ_mime_mhs_bodies		OBJ_mime_mhs,2L
+
+#define SN_id_hex_partial_message		"id-hex-partial-message"
+#define LN_id_hex_partial_message		"id-hex-partial-message"
+#define NID_id_hex_partial_message		507
+#define OBJ_id_hex_partial_message		OBJ_mime_mhs_headings,1L
+
+#define SN_id_hex_multipart_message		"id-hex-multipart-message"
+#define LN_id_hex_multipart_message		"id-hex-multipart-message"
+#define NID_id_hex_multipart_message		508
+#define OBJ_id_hex_multipart_message		OBJ_mime_mhs_headings,2L
+
+#define SN_rle_compression		"RLE"
+#define LN_rle_compression		"run length compression"
+#define NID_rle_compression		124
+#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression		"ZLIB"
+#define LN_zlib_compression		"zlib compression"
+#define NID_zlib_compression		125
+#define OBJ_zlib_compression		1L,1L,1L,1L,666L,2L
+
+#define OBJ_csor		2L,16L,840L,1L,101L,3L
+
+#define OBJ_nistAlgorithms		OBJ_csor,4L
+
+#define OBJ_aes		OBJ_nistAlgorithms,1L
+
+#define SN_aes_128_ecb		"AES-128-ECB"
+#define LN_aes_128_ecb		"aes-128-ecb"
+#define NID_aes_128_ecb		418
+#define OBJ_aes_128_ecb		OBJ_aes,1L
+
+#define SN_aes_128_cbc		"AES-128-CBC"
+#define LN_aes_128_cbc		"aes-128-cbc"
+#define NID_aes_128_cbc		419
+#define OBJ_aes_128_cbc		OBJ_aes,2L
+
+#define SN_aes_128_ofb128		"AES-128-OFB"
+#define LN_aes_128_ofb128		"aes-128-ofb"
+#define NID_aes_128_ofb128		420
+#define OBJ_aes_128_ofb128		OBJ_aes,3L
+
+#define SN_aes_128_cfb128		"AES-128-CFB"
+#define LN_aes_128_cfb128		"aes-128-cfb"
+#define NID_aes_128_cfb128		421
+#define OBJ_aes_128_cfb128		OBJ_aes,4L
+
+#define SN_aes_192_ecb		"AES-192-ECB"
+#define LN_aes_192_ecb		"aes-192-ecb"
+#define NID_aes_192_ecb		422
+#define OBJ_aes_192_ecb		OBJ_aes,21L
+
+#define SN_aes_192_cbc		"AES-192-CBC"
+#define LN_aes_192_cbc		"aes-192-cbc"
+#define NID_aes_192_cbc		423
+#define OBJ_aes_192_cbc		OBJ_aes,22L
+
+#define SN_aes_192_ofb128		"AES-192-OFB"
+#define LN_aes_192_ofb128		"aes-192-ofb"
+#define NID_aes_192_ofb128		424
+#define OBJ_aes_192_ofb128		OBJ_aes,23L
+
+#define SN_aes_192_cfb128		"AES-192-CFB"
+#define LN_aes_192_cfb128		"aes-192-cfb"
+#define NID_aes_192_cfb128		425
+#define OBJ_aes_192_cfb128		OBJ_aes,24L
+
+#define SN_aes_256_ecb		"AES-256-ECB"
+#define LN_aes_256_ecb		"aes-256-ecb"
+#define NID_aes_256_ecb		426
+#define OBJ_aes_256_ecb		OBJ_aes,41L
+
+#define SN_aes_256_cbc		"AES-256-CBC"
+#define LN_aes_256_cbc		"aes-256-cbc"
+#define NID_aes_256_cbc		427
+#define OBJ_aes_256_cbc		OBJ_aes,42L
+
+#define SN_aes_256_ofb128		"AES-256-OFB"
+#define LN_aes_256_ofb128		"aes-256-ofb"
+#define NID_aes_256_ofb128		428
+#define OBJ_aes_256_ofb128		OBJ_aes,43L
+
+#define SN_aes_256_cfb128		"AES-256-CFB"
+#define LN_aes_256_cfb128		"aes-256-cfb"
+#define NID_aes_256_cfb128		429
+#define OBJ_aes_256_cfb128		OBJ_aes,44L
+
+#define SN_aes_128_cfb1		"AES-128-CFB1"
+#define LN_aes_128_cfb1		"aes-128-cfb1"
+#define NID_aes_128_cfb1		650
+
+#define SN_aes_192_cfb1		"AES-192-CFB1"
+#define LN_aes_192_cfb1		"aes-192-cfb1"
+#define NID_aes_192_cfb1		651
+
+#define SN_aes_256_cfb1		"AES-256-CFB1"
+#define LN_aes_256_cfb1		"aes-256-cfb1"
+#define NID_aes_256_cfb1		652
+
+#define SN_aes_128_cfb8		"AES-128-CFB8"
+#define LN_aes_128_cfb8		"aes-128-cfb8"
+#define NID_aes_128_cfb8		653
+
+#define SN_aes_192_cfb8		"AES-192-CFB8"
+#define LN_aes_192_cfb8		"aes-192-cfb8"
+#define NID_aes_192_cfb8		654
+
+#define SN_aes_256_cfb8		"AES-256-CFB8"
+#define LN_aes_256_cfb8		"aes-256-cfb8"
+#define NID_aes_256_cfb8		655
+
+#define SN_des_cfb1		"DES-CFB1"
+#define LN_des_cfb1		"des-cfb1"
+#define NID_des_cfb1		656
+
+#define SN_des_cfb8		"DES-CFB8"
+#define LN_des_cfb8		"des-cfb8"
+#define NID_des_cfb8		657
+
+#define SN_des_ede3_cfb1		"DES-EDE3-CFB1"
+#define LN_des_ede3_cfb1		"des-ede3-cfb1"
+#define NID_des_ede3_cfb1		658
+
+#define SN_des_ede3_cfb8		"DES-EDE3-CFB8"
+#define LN_des_ede3_cfb8		"des-ede3-cfb8"
+#define NID_des_ede3_cfb8		659
+
+#define OBJ_nist_hashalgs		OBJ_nistAlgorithms,2L
+
+#define SN_sha256		"SHA256"
+#define LN_sha256		"sha256"
+#define NID_sha256		672
+#define OBJ_sha256		OBJ_nist_hashalgs,1L
+
+#define SN_sha384		"SHA384"
+#define LN_sha384		"sha384"
+#define NID_sha384		673
+#define OBJ_sha384		OBJ_nist_hashalgs,2L
+
+#define SN_sha512		"SHA512"
+#define LN_sha512		"sha512"
+#define NID_sha512		674
+#define OBJ_sha512		OBJ_nist_hashalgs,3L
+
+#define SN_sha224		"SHA224"
+#define LN_sha224		"sha224"
+#define NID_sha224		675
+#define OBJ_sha224		OBJ_nist_hashalgs,4L
+
+#define SN_hold_instruction_code		"holdInstructionCode"
+#define LN_hold_instruction_code		"Hold Instruction Code"
+#define NID_hold_instruction_code		430
+#define OBJ_hold_instruction_code		OBJ_id_ce,23L
+
+#define OBJ_holdInstruction		OBJ_X9_57,2L
+
+#define SN_hold_instruction_none		"holdInstructionNone"
+#define LN_hold_instruction_none		"Hold Instruction None"
+#define NID_hold_instruction_none		431
+#define OBJ_hold_instruction_none		OBJ_holdInstruction,1L
+
+#define SN_hold_instruction_call_issuer		"holdInstructionCallIssuer"
+#define LN_hold_instruction_call_issuer		"Hold Instruction Call Issuer"
+#define NID_hold_instruction_call_issuer		432
+#define OBJ_hold_instruction_call_issuer		OBJ_holdInstruction,2L
+
+#define SN_hold_instruction_reject		"holdInstructionReject"
+#define LN_hold_instruction_reject		"Hold Instruction Reject"
+#define NID_hold_instruction_reject		433
+#define OBJ_hold_instruction_reject		OBJ_holdInstruction,3L
+
+#define SN_data		"data"
+#define NID_data		434
+#define OBJ_data		OBJ_itu_t,9L
+
+#define SN_pss		"pss"
+#define NID_pss		435
+#define OBJ_pss		OBJ_data,2342L
+
+#define SN_ucl		"ucl"
+#define NID_ucl		436
+#define OBJ_ucl		OBJ_pss,19200300L
+
+#define SN_pilot		"pilot"
+#define NID_pilot		437
+#define OBJ_pilot		OBJ_ucl,100L
+
+#define LN_pilotAttributeType		"pilotAttributeType"
+#define NID_pilotAttributeType		438
+#define OBJ_pilotAttributeType		OBJ_pilot,1L
+
+#define LN_pilotAttributeSyntax		"pilotAttributeSyntax"
+#define NID_pilotAttributeSyntax		439
+#define OBJ_pilotAttributeSyntax		OBJ_pilot,3L
+
+#define LN_pilotObjectClass		"pilotObjectClass"
+#define NID_pilotObjectClass		440
+#define OBJ_pilotObjectClass		OBJ_pilot,4L
+
+#define LN_pilotGroups		"pilotGroups"
+#define NID_pilotGroups		441
+#define OBJ_pilotGroups		OBJ_pilot,10L
+
+#define LN_iA5StringSyntax		"iA5StringSyntax"
+#define NID_iA5StringSyntax		442
+#define OBJ_iA5StringSyntax		OBJ_pilotAttributeSyntax,4L
+
+#define LN_caseIgnoreIA5StringSyntax		"caseIgnoreIA5StringSyntax"
+#define NID_caseIgnoreIA5StringSyntax		443
+#define OBJ_caseIgnoreIA5StringSyntax		OBJ_pilotAttributeSyntax,5L
+
+#define LN_pilotObject		"pilotObject"
+#define NID_pilotObject		444
+#define OBJ_pilotObject		OBJ_pilotObjectClass,3L
+
+#define LN_pilotPerson		"pilotPerson"
+#define NID_pilotPerson		445
+#define OBJ_pilotPerson		OBJ_pilotObjectClass,4L
+
+#define SN_account		"account"
+#define NID_account		446
+#define OBJ_account		OBJ_pilotObjectClass,5L
+
+#define SN_document		"document"
+#define NID_document		447
+#define OBJ_document		OBJ_pilotObjectClass,6L
+
+#define SN_room		"room"
+#define NID_room		448
+#define OBJ_room		OBJ_pilotObjectClass,7L
+
+#define LN_documentSeries		"documentSeries"
+#define NID_documentSeries		449
+#define OBJ_documentSeries		OBJ_pilotObjectClass,9L
+
+#define SN_Domain		"domain"
+#define LN_Domain		"Domain"
+#define NID_Domain		392
+#define OBJ_Domain		OBJ_pilotObjectClass,13L
+
+#define LN_rFC822localPart		"rFC822localPart"
+#define NID_rFC822localPart		450
+#define OBJ_rFC822localPart		OBJ_pilotObjectClass,14L
+
+#define LN_dNSDomain		"dNSDomain"
+#define NID_dNSDomain		451
+#define OBJ_dNSDomain		OBJ_pilotObjectClass,15L
+
+#define LN_domainRelatedObject		"domainRelatedObject"
+#define NID_domainRelatedObject		452
+#define OBJ_domainRelatedObject		OBJ_pilotObjectClass,17L
+
+#define LN_friendlyCountry		"friendlyCountry"
+#define NID_friendlyCountry		453
+#define OBJ_friendlyCountry		OBJ_pilotObjectClass,18L
+
+#define LN_simpleSecurityObject		"simpleSecurityObject"
+#define NID_simpleSecurityObject		454
+#define OBJ_simpleSecurityObject		OBJ_pilotObjectClass,19L
+
+#define LN_pilotOrganization		"pilotOrganization"
+#define NID_pilotOrganization		455
+#define OBJ_pilotOrganization		OBJ_pilotObjectClass,20L
+
+#define LN_pilotDSA		"pilotDSA"
+#define NID_pilotDSA		456
+#define OBJ_pilotDSA		OBJ_pilotObjectClass,21L
+
+#define LN_qualityLabelledData		"qualityLabelledData"
+#define NID_qualityLabelledData		457
+#define OBJ_qualityLabelledData		OBJ_pilotObjectClass,22L
+
+#define SN_userId		"UID"
+#define LN_userId		"userId"
+#define NID_userId		458
+#define OBJ_userId		OBJ_pilotAttributeType,1L
+
+#define LN_textEncodedORAddress		"textEncodedORAddress"
+#define NID_textEncodedORAddress		459
+#define OBJ_textEncodedORAddress		OBJ_pilotAttributeType,2L
+
+#define SN_rfc822Mailbox		"mail"
+#define LN_rfc822Mailbox		"rfc822Mailbox"
+#define NID_rfc822Mailbox		460
+#define OBJ_rfc822Mailbox		OBJ_pilotAttributeType,3L
+
+#define SN_info		"info"
+#define NID_info		461
+#define OBJ_info		OBJ_pilotAttributeType,4L
+
+#define LN_favouriteDrink		"favouriteDrink"
+#define NID_favouriteDrink		462
+#define OBJ_favouriteDrink		OBJ_pilotAttributeType,5L
+
+#define LN_roomNumber		"roomNumber"
+#define NID_roomNumber		463
+#define OBJ_roomNumber		OBJ_pilotAttributeType,6L
+
+#define SN_photo		"photo"
+#define NID_photo		464
+#define OBJ_photo		OBJ_pilotAttributeType,7L
+
+#define LN_userClass		"userClass"
+#define NID_userClass		465
+#define OBJ_userClass		OBJ_pilotAttributeType,8L
+
+#define SN_host		"host"
+#define NID_host		466
+#define OBJ_host		OBJ_pilotAttributeType,9L
+
+#define SN_manager		"manager"
+#define NID_manager		467
+#define OBJ_manager		OBJ_pilotAttributeType,10L
+
+#define LN_documentIdentifier		"documentIdentifier"
+#define NID_documentIdentifier		468
+#define OBJ_documentIdentifier		OBJ_pilotAttributeType,11L
+
+#define LN_documentTitle		"documentTitle"
+#define NID_documentTitle		469
+#define OBJ_documentTitle		OBJ_pilotAttributeType,12L
+
+#define LN_documentVersion		"documentVersion"
+#define NID_documentVersion		470
+#define OBJ_documentVersion		OBJ_pilotAttributeType,13L
+
+#define LN_documentAuthor		"documentAuthor"
+#define NID_documentAuthor		471
+#define OBJ_documentAuthor		OBJ_pilotAttributeType,14L
+
+#define LN_documentLocation		"documentLocation"
+#define NID_documentLocation		472
+#define OBJ_documentLocation		OBJ_pilotAttributeType,15L
+
+#define LN_homeTelephoneNumber		"homeTelephoneNumber"
+#define NID_homeTelephoneNumber		473
+#define OBJ_homeTelephoneNumber		OBJ_pilotAttributeType,20L
+
+#define SN_secretary		"secretary"
+#define NID_secretary		474
+#define OBJ_secretary		OBJ_pilotAttributeType,21L
+
+#define LN_otherMailbox		"otherMailbox"
+#define NID_otherMailbox		475
+#define OBJ_otherMailbox		OBJ_pilotAttributeType,22L
+
+#define LN_lastModifiedTime		"lastModifiedTime"
+#define NID_lastModifiedTime		476
+#define OBJ_lastModifiedTime		OBJ_pilotAttributeType,23L
+
+#define LN_lastModifiedBy		"lastModifiedBy"
+#define NID_lastModifiedBy		477
+#define OBJ_lastModifiedBy		OBJ_pilotAttributeType,24L
+
+#define SN_domainComponent		"DC"
+#define LN_domainComponent		"domainComponent"
+#define NID_domainComponent		391
+#define OBJ_domainComponent		OBJ_pilotAttributeType,25L
+
+#define LN_aRecord		"aRecord"
+#define NID_aRecord		478
+#define OBJ_aRecord		OBJ_pilotAttributeType,26L
+
+#define LN_pilotAttributeType27		"pilotAttributeType27"
+#define NID_pilotAttributeType27		479
+#define OBJ_pilotAttributeType27		OBJ_pilotAttributeType,27L
+
+#define LN_mXRecord		"mXRecord"
+#define NID_mXRecord		480
+#define OBJ_mXRecord		OBJ_pilotAttributeType,28L
+
+#define LN_nSRecord		"nSRecord"
+#define NID_nSRecord		481
+#define OBJ_nSRecord		OBJ_pilotAttributeType,29L
+
+#define LN_sOARecord		"sOARecord"
+#define NID_sOARecord		482
+#define OBJ_sOARecord		OBJ_pilotAttributeType,30L
+
+#define LN_cNAMERecord		"cNAMERecord"
+#define NID_cNAMERecord		483
+#define OBJ_cNAMERecord		OBJ_pilotAttributeType,31L
+
+#define LN_associatedDomain		"associatedDomain"
+#define NID_associatedDomain		484
+#define OBJ_associatedDomain		OBJ_pilotAttributeType,37L
+
+#define LN_associatedName		"associatedName"
+#define NID_associatedName		485
+#define OBJ_associatedName		OBJ_pilotAttributeType,38L
+
+#define LN_homePostalAddress		"homePostalAddress"
+#define NID_homePostalAddress		486
+#define OBJ_homePostalAddress		OBJ_pilotAttributeType,39L
+
+#define LN_personalTitle		"personalTitle"
+#define NID_personalTitle		487
+#define OBJ_personalTitle		OBJ_pilotAttributeType,40L
+
+#define LN_mobileTelephoneNumber		"mobileTelephoneNumber"
+#define NID_mobileTelephoneNumber		488
+#define OBJ_mobileTelephoneNumber		OBJ_pilotAttributeType,41L
+
+#define LN_pagerTelephoneNumber		"pagerTelephoneNumber"
+#define NID_pagerTelephoneNumber		489
+#define OBJ_pagerTelephoneNumber		OBJ_pilotAttributeType,42L
+
+#define LN_friendlyCountryName		"friendlyCountryName"
+#define NID_friendlyCountryName		490
+#define OBJ_friendlyCountryName		OBJ_pilotAttributeType,43L
+
+#define LN_organizationalStatus		"organizationalStatus"
+#define NID_organizationalStatus		491
+#define OBJ_organizationalStatus		OBJ_pilotAttributeType,45L
+
+#define LN_janetMailbox		"janetMailbox"
+#define NID_janetMailbox		492
+#define OBJ_janetMailbox		OBJ_pilotAttributeType,46L
+
+#define LN_mailPreferenceOption		"mailPreferenceOption"
+#define NID_mailPreferenceOption		493
+#define OBJ_mailPreferenceOption		OBJ_pilotAttributeType,47L
+
+#define LN_buildingName		"buildingName"
+#define NID_buildingName		494
+#define OBJ_buildingName		OBJ_pilotAttributeType,48L
+
+#define LN_dSAQuality		"dSAQuality"
+#define NID_dSAQuality		495
+#define OBJ_dSAQuality		OBJ_pilotAttributeType,49L
+
+#define LN_singleLevelQuality		"singleLevelQuality"
+#define NID_singleLevelQuality		496
+#define OBJ_singleLevelQuality		OBJ_pilotAttributeType,50L
+
+#define LN_subtreeMinimumQuality		"subtreeMinimumQuality"
+#define NID_subtreeMinimumQuality		497
+#define OBJ_subtreeMinimumQuality		OBJ_pilotAttributeType,51L
+
+#define LN_subtreeMaximumQuality		"subtreeMaximumQuality"
+#define NID_subtreeMaximumQuality		498
+#define OBJ_subtreeMaximumQuality		OBJ_pilotAttributeType,52L
+
+#define LN_personalSignature		"personalSignature"
+#define NID_personalSignature		499
+#define OBJ_personalSignature		OBJ_pilotAttributeType,53L
+
+#define LN_dITRedirect		"dITRedirect"
+#define NID_dITRedirect		500
+#define OBJ_dITRedirect		OBJ_pilotAttributeType,54L
+
+#define SN_audio		"audio"
+#define NID_audio		501
+#define OBJ_audio		OBJ_pilotAttributeType,55L
+
+#define LN_documentPublisher		"documentPublisher"
+#define NID_documentPublisher		502
+#define OBJ_documentPublisher		OBJ_pilotAttributeType,56L
+
+#define SN_id_set		"id-set"
+#define LN_id_set		"Secure Electronic Transactions"
+#define NID_id_set		512
+#define OBJ_id_set		OBJ_international_organizations,42L
+
+#define SN_set_ctype		"set-ctype"
+#define LN_set_ctype		"content types"
+#define NID_set_ctype		513
+#define OBJ_set_ctype		OBJ_id_set,0L
+
+#define SN_set_msgExt		"set-msgExt"
+#define LN_set_msgExt		"message extensions"
+#define NID_set_msgExt		514
+#define OBJ_set_msgExt		OBJ_id_set,1L
+
+#define SN_set_attr		"set-attr"
+#define NID_set_attr		515
+#define OBJ_set_attr		OBJ_id_set,3L
+
+#define SN_set_policy		"set-policy"
+#define NID_set_policy		516
+#define OBJ_set_policy		OBJ_id_set,5L
+
+#define SN_set_certExt		"set-certExt"
+#define LN_set_certExt		"certificate extensions"
+#define NID_set_certExt		517
+#define OBJ_set_certExt		OBJ_id_set,7L
+
+#define SN_set_brand		"set-brand"
+#define NID_set_brand		518
+#define OBJ_set_brand		OBJ_id_set,8L
+
+#define SN_setct_PANData		"setct-PANData"
+#define NID_setct_PANData		519
+#define OBJ_setct_PANData		OBJ_set_ctype,0L
+
+#define SN_setct_PANToken		"setct-PANToken"
+#define NID_setct_PANToken		520
+#define OBJ_setct_PANToken		OBJ_set_ctype,1L
+
+#define SN_setct_PANOnly		"setct-PANOnly"
+#define NID_setct_PANOnly		521
+#define OBJ_setct_PANOnly		OBJ_set_ctype,2L
+
+#define SN_setct_OIData		"setct-OIData"
+#define NID_setct_OIData		522
+#define OBJ_setct_OIData		OBJ_set_ctype,3L
+
+#define SN_setct_PI		"setct-PI"
+#define NID_setct_PI		523
+#define OBJ_setct_PI		OBJ_set_ctype,4L
+
+#define SN_setct_PIData		"setct-PIData"
+#define NID_setct_PIData		524
+#define OBJ_setct_PIData		OBJ_set_ctype,5L
+
+#define SN_setct_PIDataUnsigned		"setct-PIDataUnsigned"
+#define NID_setct_PIDataUnsigned		525
+#define OBJ_setct_PIDataUnsigned		OBJ_set_ctype,6L
+
+#define SN_setct_HODInput		"setct-HODInput"
+#define NID_setct_HODInput		526
+#define OBJ_setct_HODInput		OBJ_set_ctype,7L
+
+#define SN_setct_AuthResBaggage		"setct-AuthResBaggage"
+#define NID_setct_AuthResBaggage		527
+#define OBJ_setct_AuthResBaggage		OBJ_set_ctype,8L
+
+#define SN_setct_AuthRevReqBaggage		"setct-AuthRevReqBaggage"
+#define NID_setct_AuthRevReqBaggage		528
+#define OBJ_setct_AuthRevReqBaggage		OBJ_set_ctype,9L
+
+#define SN_setct_AuthRevResBaggage		"setct-AuthRevResBaggage"
+#define NID_setct_AuthRevResBaggage		529
+#define OBJ_setct_AuthRevResBaggage		OBJ_set_ctype,10L
+
+#define SN_setct_CapTokenSeq		"setct-CapTokenSeq"
+#define NID_setct_CapTokenSeq		530
+#define OBJ_setct_CapTokenSeq		OBJ_set_ctype,11L
+
+#define SN_setct_PInitResData		"setct-PInitResData"
+#define NID_setct_PInitResData		531
+#define OBJ_setct_PInitResData		OBJ_set_ctype,12L
+
+#define SN_setct_PI_TBS		"setct-PI-TBS"
+#define NID_setct_PI_TBS		532
+#define OBJ_setct_PI_TBS		OBJ_set_ctype,13L
+
+#define SN_setct_PResData		"setct-PResData"
+#define NID_setct_PResData		533
+#define OBJ_setct_PResData		OBJ_set_ctype,14L
+
+#define SN_setct_AuthReqTBS		"setct-AuthReqTBS"
+#define NID_setct_AuthReqTBS		534
+#define OBJ_setct_AuthReqTBS		OBJ_set_ctype,16L
+
+#define SN_setct_AuthResTBS		"setct-AuthResTBS"
+#define NID_setct_AuthResTBS		535
+#define OBJ_setct_AuthResTBS		OBJ_set_ctype,17L
+
+#define SN_setct_AuthResTBSX		"setct-AuthResTBSX"
+#define NID_setct_AuthResTBSX		536
+#define OBJ_setct_AuthResTBSX		OBJ_set_ctype,18L
+
+#define SN_setct_AuthTokenTBS		"setct-AuthTokenTBS"
+#define NID_setct_AuthTokenTBS		537
+#define OBJ_setct_AuthTokenTBS		OBJ_set_ctype,19L
+
+#define SN_setct_CapTokenData		"setct-CapTokenData"
+#define NID_setct_CapTokenData		538
+#define OBJ_setct_CapTokenData		OBJ_set_ctype,20L
+
+#define SN_setct_CapTokenTBS		"setct-CapTokenTBS"
+#define NID_setct_CapTokenTBS		539
+#define OBJ_setct_CapTokenTBS		OBJ_set_ctype,21L
+
+#define SN_setct_AcqCardCodeMsg		"setct-AcqCardCodeMsg"
+#define NID_setct_AcqCardCodeMsg		540
+#define OBJ_setct_AcqCardCodeMsg		OBJ_set_ctype,22L
+
+#define SN_setct_AuthRevReqTBS		"setct-AuthRevReqTBS"
+#define NID_setct_AuthRevReqTBS		541
+#define OBJ_setct_AuthRevReqTBS		OBJ_set_ctype,23L
+
+#define SN_setct_AuthRevResData		"setct-AuthRevResData"
+#define NID_setct_AuthRevResData		542
+#define OBJ_setct_AuthRevResData		OBJ_set_ctype,24L
+
+#define SN_setct_AuthRevResTBS		"setct-AuthRevResTBS"
+#define NID_setct_AuthRevResTBS		543
+#define OBJ_setct_AuthRevResTBS		OBJ_set_ctype,25L
+
+#define SN_setct_CapReqTBS		"setct-CapReqTBS"
+#define NID_setct_CapReqTBS		544
+#define OBJ_setct_CapReqTBS		OBJ_set_ctype,26L
+
+#define SN_setct_CapReqTBSX		"setct-CapReqTBSX"
+#define NID_setct_CapReqTBSX		545
+#define OBJ_setct_CapReqTBSX		OBJ_set_ctype,27L
+
+#define SN_setct_CapResData		"setct-CapResData"
+#define NID_setct_CapResData		546
+#define OBJ_setct_CapResData		OBJ_set_ctype,28L
+
+#define SN_setct_CapRevReqTBS		"setct-CapRevReqTBS"
+#define NID_setct_CapRevReqTBS		547
+#define OBJ_setct_CapRevReqTBS		OBJ_set_ctype,29L
+
+#define SN_setct_CapRevReqTBSX		"setct-CapRevReqTBSX"
+#define NID_setct_CapRevReqTBSX		548
+#define OBJ_setct_CapRevReqTBSX		OBJ_set_ctype,30L
+
+#define SN_setct_CapRevResData		"setct-CapRevResData"
+#define NID_setct_CapRevResData		549
+#define OBJ_setct_CapRevResData		OBJ_set_ctype,31L
+
+#define SN_setct_CredReqTBS		"setct-CredReqTBS"
+#define NID_setct_CredReqTBS		550
+#define OBJ_setct_CredReqTBS		OBJ_set_ctype,32L
+
+#define SN_setct_CredReqTBSX		"setct-CredReqTBSX"
+#define NID_setct_CredReqTBSX		551
+#define OBJ_setct_CredReqTBSX		OBJ_set_ctype,33L
+
+#define SN_setct_CredResData		"setct-CredResData"
+#define NID_setct_CredResData		552
+#define OBJ_setct_CredResData		OBJ_set_ctype,34L
+
+#define SN_setct_CredRevReqTBS		"setct-CredRevReqTBS"
+#define NID_setct_CredRevReqTBS		553
+#define OBJ_setct_CredRevReqTBS		OBJ_set_ctype,35L
+
+#define SN_setct_CredRevReqTBSX		"setct-CredRevReqTBSX"
+#define NID_setct_CredRevReqTBSX		554
+#define OBJ_setct_CredRevReqTBSX		OBJ_set_ctype,36L
+
+#define SN_setct_CredRevResData		"setct-CredRevResData"
+#define NID_setct_CredRevResData		555
+#define OBJ_setct_CredRevResData		OBJ_set_ctype,37L
+
+#define SN_setct_PCertReqData		"setct-PCertReqData"
+#define NID_setct_PCertReqData		556
+#define OBJ_setct_PCertReqData		OBJ_set_ctype,38L
+
+#define SN_setct_PCertResTBS		"setct-PCertResTBS"
+#define NID_setct_PCertResTBS		557
+#define OBJ_setct_PCertResTBS		OBJ_set_ctype,39L
+
+#define SN_setct_BatchAdminReqData		"setct-BatchAdminReqData"
+#define NID_setct_BatchAdminReqData		558
+#define OBJ_setct_BatchAdminReqData		OBJ_set_ctype,40L
+
+#define SN_setct_BatchAdminResData		"setct-BatchAdminResData"
+#define NID_setct_BatchAdminResData		559
+#define OBJ_setct_BatchAdminResData		OBJ_set_ctype,41L
+
+#define SN_setct_CardCInitResTBS		"setct-CardCInitResTBS"
+#define NID_setct_CardCInitResTBS		560
+#define OBJ_setct_CardCInitResTBS		OBJ_set_ctype,42L
+
+#define SN_setct_MeAqCInitResTBS		"setct-MeAqCInitResTBS"
+#define NID_setct_MeAqCInitResTBS		561
+#define OBJ_setct_MeAqCInitResTBS		OBJ_set_ctype,43L
+
+#define SN_setct_RegFormResTBS		"setct-RegFormResTBS"
+#define NID_setct_RegFormResTBS		562
+#define OBJ_setct_RegFormResTBS		OBJ_set_ctype,44L
+
+#define SN_setct_CertReqData		"setct-CertReqData"
+#define NID_setct_CertReqData		563
+#define OBJ_setct_CertReqData		OBJ_set_ctype,45L
+
+#define SN_setct_CertReqTBS		"setct-CertReqTBS"
+#define NID_setct_CertReqTBS		564
+#define OBJ_setct_CertReqTBS		OBJ_set_ctype,46L
+
+#define SN_setct_CertResData		"setct-CertResData"
+#define NID_setct_CertResData		565
+#define OBJ_setct_CertResData		OBJ_set_ctype,47L
+
+#define SN_setct_CertInqReqTBS		"setct-CertInqReqTBS"
+#define NID_setct_CertInqReqTBS		566
+#define OBJ_setct_CertInqReqTBS		OBJ_set_ctype,48L
+
+#define SN_setct_ErrorTBS		"setct-ErrorTBS"
+#define NID_setct_ErrorTBS		567
+#define OBJ_setct_ErrorTBS		OBJ_set_ctype,49L
+
+#define SN_setct_PIDualSignedTBE		"setct-PIDualSignedTBE"
+#define NID_setct_PIDualSignedTBE		568
+#define OBJ_setct_PIDualSignedTBE		OBJ_set_ctype,50L
+
+#define SN_setct_PIUnsignedTBE		"setct-PIUnsignedTBE"
+#define NID_setct_PIUnsignedTBE		569
+#define OBJ_setct_PIUnsignedTBE		OBJ_set_ctype,51L
+
+#define SN_setct_AuthReqTBE		"setct-AuthReqTBE"
+#define NID_setct_AuthReqTBE		570
+#define OBJ_setct_AuthReqTBE		OBJ_set_ctype,52L
+
+#define SN_setct_AuthResTBE		"setct-AuthResTBE"
+#define NID_setct_AuthResTBE		571
+#define OBJ_setct_AuthResTBE		OBJ_set_ctype,53L
+
+#define SN_setct_AuthResTBEX		"setct-AuthResTBEX"
+#define NID_setct_AuthResTBEX		572
+#define OBJ_setct_AuthResTBEX		OBJ_set_ctype,54L
+
+#define SN_setct_AuthTokenTBE		"setct-AuthTokenTBE"
+#define NID_setct_AuthTokenTBE		573
+#define OBJ_setct_AuthTokenTBE		OBJ_set_ctype,55L
+
+#define SN_setct_CapTokenTBE		"setct-CapTokenTBE"
+#define NID_setct_CapTokenTBE		574
+#define OBJ_setct_CapTokenTBE		OBJ_set_ctype,56L
+
+#define SN_setct_CapTokenTBEX		"setct-CapTokenTBEX"
+#define NID_setct_CapTokenTBEX		575
+#define OBJ_setct_CapTokenTBEX		OBJ_set_ctype,57L
+
+#define SN_setct_AcqCardCodeMsgTBE		"setct-AcqCardCodeMsgTBE"
+#define NID_setct_AcqCardCodeMsgTBE		576
+#define OBJ_setct_AcqCardCodeMsgTBE		OBJ_set_ctype,58L
+
+#define SN_setct_AuthRevReqTBE		"setct-AuthRevReqTBE"
+#define NID_setct_AuthRevReqTBE		577
+#define OBJ_setct_AuthRevReqTBE		OBJ_set_ctype,59L
+
+#define SN_setct_AuthRevResTBE		"setct-AuthRevResTBE"
+#define NID_setct_AuthRevResTBE		578
+#define OBJ_setct_AuthRevResTBE		OBJ_set_ctype,60L
+
+#define SN_setct_AuthRevResTBEB		"setct-AuthRevResTBEB"
+#define NID_setct_AuthRevResTBEB		579
+#define OBJ_setct_AuthRevResTBEB		OBJ_set_ctype,61L
+
+#define SN_setct_CapReqTBE		"setct-CapReqTBE"
+#define NID_setct_CapReqTBE		580
+#define OBJ_setct_CapReqTBE		OBJ_set_ctype,62L
+
+#define SN_setct_CapReqTBEX		"setct-CapReqTBEX"
+#define NID_setct_CapReqTBEX		581
+#define OBJ_setct_CapReqTBEX		OBJ_set_ctype,63L
+
+#define SN_setct_CapResTBE		"setct-CapResTBE"
+#define NID_setct_CapResTBE		582
+#define OBJ_setct_CapResTBE		OBJ_set_ctype,64L
+
+#define SN_setct_CapRevReqTBE		"setct-CapRevReqTBE"
+#define NID_setct_CapRevReqTBE		583
+#define OBJ_setct_CapRevReqTBE		OBJ_set_ctype,65L
+
+#define SN_setct_CapRevReqTBEX		"setct-CapRevReqTBEX"
+#define NID_setct_CapRevReqTBEX		584
+#define OBJ_setct_CapRevReqTBEX		OBJ_set_ctype,66L
+
+#define SN_setct_CapRevResTBE		"setct-CapRevResTBE"
+#define NID_setct_CapRevResTBE		585
+#define OBJ_setct_CapRevResTBE		OBJ_set_ctype,67L
+
+#define SN_setct_CredReqTBE		"setct-CredReqTBE"
+#define NID_setct_CredReqTBE		586
+#define OBJ_setct_CredReqTBE		OBJ_set_ctype,68L
+
+#define SN_setct_CredReqTBEX		"setct-CredReqTBEX"
+#define NID_setct_CredReqTBEX		587
+#define OBJ_setct_CredReqTBEX		OBJ_set_ctype,69L
+
+#define SN_setct_CredResTBE		"setct-CredResTBE"
+#define NID_setct_CredResTBE		588
+#define OBJ_setct_CredResTBE		OBJ_set_ctype,70L
+
+#define SN_setct_CredRevReqTBE		"setct-CredRevReqTBE"
+#define NID_setct_CredRevReqTBE		589
+#define OBJ_setct_CredRevReqTBE		OBJ_set_ctype,71L
+
+#define SN_setct_CredRevReqTBEX		"setct-CredRevReqTBEX"
+#define NID_setct_CredRevReqTBEX		590
+#define OBJ_setct_CredRevReqTBEX		OBJ_set_ctype,72L
+
+#define SN_setct_CredRevResTBE		"setct-CredRevResTBE"
+#define NID_setct_CredRevResTBE		591
+#define OBJ_setct_CredRevResTBE		OBJ_set_ctype,73L
+
+#define SN_setct_BatchAdminReqTBE		"setct-BatchAdminReqTBE"
+#define NID_setct_BatchAdminReqTBE		592
+#define OBJ_setct_BatchAdminReqTBE		OBJ_set_ctype,74L
+
+#define SN_setct_BatchAdminResTBE		"setct-BatchAdminResTBE"
+#define NID_setct_BatchAdminResTBE		593
+#define OBJ_setct_BatchAdminResTBE		OBJ_set_ctype,75L
+
+#define SN_setct_RegFormReqTBE		"setct-RegFormReqTBE"
+#define NID_setct_RegFormReqTBE		594
+#define OBJ_setct_RegFormReqTBE		OBJ_set_ctype,76L
+
+#define SN_setct_CertReqTBE		"setct-CertReqTBE"
+#define NID_setct_CertReqTBE		595
+#define OBJ_setct_CertReqTBE		OBJ_set_ctype,77L
+
+#define SN_setct_CertReqTBEX		"setct-CertReqTBEX"
+#define NID_setct_CertReqTBEX		596
+#define OBJ_setct_CertReqTBEX		OBJ_set_ctype,78L
+
+#define SN_setct_CertResTBE		"setct-CertResTBE"
+#define NID_setct_CertResTBE		597
+#define OBJ_setct_CertResTBE		OBJ_set_ctype,79L
+
+#define SN_setct_CRLNotificationTBS		"setct-CRLNotificationTBS"
+#define NID_setct_CRLNotificationTBS		598
+#define OBJ_setct_CRLNotificationTBS		OBJ_set_ctype,80L
+
+#define SN_setct_CRLNotificationResTBS		"setct-CRLNotificationResTBS"
+#define NID_setct_CRLNotificationResTBS		599
+#define OBJ_setct_CRLNotificationResTBS		OBJ_set_ctype,81L
+
+#define SN_setct_BCIDistributionTBS		"setct-BCIDistributionTBS"
+#define NID_setct_BCIDistributionTBS		600
+#define OBJ_setct_BCIDistributionTBS		OBJ_set_ctype,82L
+
+#define SN_setext_genCrypt		"setext-genCrypt"
+#define LN_setext_genCrypt		"generic cryptogram"
+#define NID_setext_genCrypt		601
+#define OBJ_setext_genCrypt		OBJ_set_msgExt,1L
+
+#define SN_setext_miAuth		"setext-miAuth"
+#define LN_setext_miAuth		"merchant initiated auth"
+#define NID_setext_miAuth		602
+#define OBJ_setext_miAuth		OBJ_set_msgExt,3L
+
+#define SN_setext_pinSecure		"setext-pinSecure"
+#define NID_setext_pinSecure		603
+#define OBJ_setext_pinSecure		OBJ_set_msgExt,4L
+
+#define SN_setext_pinAny		"setext-pinAny"
+#define NID_setext_pinAny		604
+#define OBJ_setext_pinAny		OBJ_set_msgExt,5L
+
+#define SN_setext_track2		"setext-track2"
+#define NID_setext_track2		605
+#define OBJ_setext_track2		OBJ_set_msgExt,7L
+
+#define SN_setext_cv		"setext-cv"
+#define LN_setext_cv		"additional verification"
+#define NID_setext_cv		606
+#define OBJ_setext_cv		OBJ_set_msgExt,8L
+
+#define SN_set_policy_root		"set-policy-root"
+#define NID_set_policy_root		607
+#define OBJ_set_policy_root		OBJ_set_policy,0L
+
+#define SN_setCext_hashedRoot		"setCext-hashedRoot"
+#define NID_setCext_hashedRoot		608
+#define OBJ_setCext_hashedRoot		OBJ_set_certExt,0L
+
+#define SN_setCext_certType		"setCext-certType"
+#define NID_setCext_certType		609
+#define OBJ_setCext_certType		OBJ_set_certExt,1L
+
+#define SN_setCext_merchData		"setCext-merchData"
+#define NID_setCext_merchData		610
+#define OBJ_setCext_merchData		OBJ_set_certExt,2L
+
+#define SN_setCext_cCertRequired		"setCext-cCertRequired"
+#define NID_setCext_cCertRequired		611
+#define OBJ_setCext_cCertRequired		OBJ_set_certExt,3L
+
+#define SN_setCext_tunneling		"setCext-tunneling"
+#define NID_setCext_tunneling		612
+#define OBJ_setCext_tunneling		OBJ_set_certExt,4L
+
+#define SN_setCext_setExt		"setCext-setExt"
+#define NID_setCext_setExt		613
+#define OBJ_setCext_setExt		OBJ_set_certExt,5L
+
+#define SN_setCext_setQualf		"setCext-setQualf"
+#define NID_setCext_setQualf		614
+#define OBJ_setCext_setQualf		OBJ_set_certExt,6L
+
+#define SN_setCext_PGWYcapabilities		"setCext-PGWYcapabilities"
+#define NID_setCext_PGWYcapabilities		615
+#define OBJ_setCext_PGWYcapabilities		OBJ_set_certExt,7L
+
+#define SN_setCext_TokenIdentifier		"setCext-TokenIdentifier"
+#define NID_setCext_TokenIdentifier		616
+#define OBJ_setCext_TokenIdentifier		OBJ_set_certExt,8L
+
+#define SN_setCext_Track2Data		"setCext-Track2Data"
+#define NID_setCext_Track2Data		617
+#define OBJ_setCext_Track2Data		OBJ_set_certExt,9L
+
+#define SN_setCext_TokenType		"setCext-TokenType"
+#define NID_setCext_TokenType		618
+#define OBJ_setCext_TokenType		OBJ_set_certExt,10L
+
+#define SN_setCext_IssuerCapabilities		"setCext-IssuerCapabilities"
+#define NID_setCext_IssuerCapabilities		619
+#define OBJ_setCext_IssuerCapabilities		OBJ_set_certExt,11L
+
+#define SN_setAttr_Cert		"setAttr-Cert"
+#define NID_setAttr_Cert		620
+#define OBJ_setAttr_Cert		OBJ_set_attr,0L
+
+#define SN_setAttr_PGWYcap		"setAttr-PGWYcap"
+#define LN_setAttr_PGWYcap		"payment gateway capabilities"
+#define NID_setAttr_PGWYcap		621
+#define OBJ_setAttr_PGWYcap		OBJ_set_attr,1L
+
+#define SN_setAttr_TokenType		"setAttr-TokenType"
+#define NID_setAttr_TokenType		622
+#define OBJ_setAttr_TokenType		OBJ_set_attr,2L
+
+#define SN_setAttr_IssCap		"setAttr-IssCap"
+#define LN_setAttr_IssCap		"issuer capabilities"
+#define NID_setAttr_IssCap		623
+#define OBJ_setAttr_IssCap		OBJ_set_attr,3L
+
+#define SN_set_rootKeyThumb		"set-rootKeyThumb"
+#define NID_set_rootKeyThumb		624
+#define OBJ_set_rootKeyThumb		OBJ_setAttr_Cert,0L
+
+#define SN_set_addPolicy		"set-addPolicy"
+#define NID_set_addPolicy		625
+#define OBJ_set_addPolicy		OBJ_setAttr_Cert,1L
+
+#define SN_setAttr_Token_EMV		"setAttr-Token-EMV"
+#define NID_setAttr_Token_EMV		626
+#define OBJ_setAttr_Token_EMV		OBJ_setAttr_TokenType,1L
+
+#define SN_setAttr_Token_B0Prime		"setAttr-Token-B0Prime"
+#define NID_setAttr_Token_B0Prime		627
+#define OBJ_setAttr_Token_B0Prime		OBJ_setAttr_TokenType,2L
+
+#define SN_setAttr_IssCap_CVM		"setAttr-IssCap-CVM"
+#define NID_setAttr_IssCap_CVM		628
+#define OBJ_setAttr_IssCap_CVM		OBJ_setAttr_IssCap,3L
+
+#define SN_setAttr_IssCap_T2		"setAttr-IssCap-T2"
+#define NID_setAttr_IssCap_T2		629
+#define OBJ_setAttr_IssCap_T2		OBJ_setAttr_IssCap,4L
+
+#define SN_setAttr_IssCap_Sig		"setAttr-IssCap-Sig"
+#define NID_setAttr_IssCap_Sig		630
+#define OBJ_setAttr_IssCap_Sig		OBJ_setAttr_IssCap,5L
+
+#define SN_setAttr_GenCryptgrm		"setAttr-GenCryptgrm"
+#define LN_setAttr_GenCryptgrm		"generate cryptogram"
+#define NID_setAttr_GenCryptgrm		631
+#define OBJ_setAttr_GenCryptgrm		OBJ_setAttr_IssCap_CVM,1L
+
+#define SN_setAttr_T2Enc		"setAttr-T2Enc"
+#define LN_setAttr_T2Enc		"encrypted track 2"
+#define NID_setAttr_T2Enc		632
+#define OBJ_setAttr_T2Enc		OBJ_setAttr_IssCap_T2,1L
+
+#define SN_setAttr_T2cleartxt		"setAttr-T2cleartxt"
+#define LN_setAttr_T2cleartxt		"cleartext track 2"
+#define NID_setAttr_T2cleartxt		633
+#define OBJ_setAttr_T2cleartxt		OBJ_setAttr_IssCap_T2,2L
+
+#define SN_setAttr_TokICCsig		"setAttr-TokICCsig"
+#define LN_setAttr_TokICCsig		"ICC or token signature"
+#define NID_setAttr_TokICCsig		634
+#define OBJ_setAttr_TokICCsig		OBJ_setAttr_IssCap_Sig,1L
+
+#define SN_setAttr_SecDevSig		"setAttr-SecDevSig"
+#define LN_setAttr_SecDevSig		"secure device signature"
+#define NID_setAttr_SecDevSig		635
+#define OBJ_setAttr_SecDevSig		OBJ_setAttr_IssCap_Sig,2L
+
+#define SN_set_brand_IATA_ATA		"set-brand-IATA-ATA"
+#define NID_set_brand_IATA_ATA		636
+#define OBJ_set_brand_IATA_ATA		OBJ_set_brand,1L
+
+#define SN_set_brand_Diners		"set-brand-Diners"
+#define NID_set_brand_Diners		637
+#define OBJ_set_brand_Diners		OBJ_set_brand,30L
+
+#define SN_set_brand_AmericanExpress		"set-brand-AmericanExpress"
+#define NID_set_brand_AmericanExpress		638
+#define OBJ_set_brand_AmericanExpress		OBJ_set_brand,34L
+
+#define SN_set_brand_JCB		"set-brand-JCB"
+#define NID_set_brand_JCB		639
+#define OBJ_set_brand_JCB		OBJ_set_brand,35L
+
+#define SN_set_brand_Visa		"set-brand-Visa"
+#define NID_set_brand_Visa		640
+#define OBJ_set_brand_Visa		OBJ_set_brand,4L
+
+#define SN_set_brand_MasterCard		"set-brand-MasterCard"
+#define NID_set_brand_MasterCard		641
+#define OBJ_set_brand_MasterCard		OBJ_set_brand,5L
+
+#define SN_set_brand_Novus		"set-brand-Novus"
+#define NID_set_brand_Novus		642
+#define OBJ_set_brand_Novus		OBJ_set_brand,6011L
+
+#define SN_des_cdmf		"DES-CDMF"
+#define LN_des_cdmf		"des-cdmf"
+#define NID_des_cdmf		643
+#define OBJ_des_cdmf		OBJ_rsadsi,3L,10L
+
+#define SN_rsaOAEPEncryptionSET		"rsaOAEPEncryptionSET"
+#define NID_rsaOAEPEncryptionSET		644
+#define OBJ_rsaOAEPEncryptionSET		OBJ_rsadsi,1L,1L,6L
+
+#define SN_ipsec3		"Oakley-EC2N-3"
+#define LN_ipsec3		"ipsec3"
+#define NID_ipsec3		749
+
+#define SN_ipsec4		"Oakley-EC2N-4"
+#define LN_ipsec4		"ipsec4"
+#define NID_ipsec4		750
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/objects.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/objects.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/objects.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,1049 @@
+/* crypto/objects/objects.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_OBJECTS_H
+#define HEADER_OBJECTS_H
+
+#define USE_OBJ_MAC
+
+#ifdef USE_OBJ_MAC
+#include <openssl/obj_mac.h>
+#else
+#define SN_undef			"UNDEF"
+#define LN_undef			"undefined"
+#define NID_undef			0
+#define OBJ_undef			0L
+
+#define SN_Algorithm			"Algorithm"
+#define LN_algorithm			"algorithm"
+#define NID_algorithm			38
+#define OBJ_algorithm			1L,3L,14L,3L,2L
+
+#define LN_rsadsi			"rsadsi"
+#define NID_rsadsi			1
+#define OBJ_rsadsi			1L,2L,840L,113549L
+
+#define LN_pkcs				"pkcs"
+#define NID_pkcs			2
+#define OBJ_pkcs			OBJ_rsadsi,1L
+
+#define SN_md2				"MD2"
+#define LN_md2				"md2"
+#define NID_md2				3
+#define OBJ_md2				OBJ_rsadsi,2L,2L
+
+#define SN_md5				"MD5"
+#define LN_md5				"md5"
+#define NID_md5				4
+#define OBJ_md5				OBJ_rsadsi,2L,5L
+
+#define SN_rc4				"RC4"
+#define LN_rc4				"rc4"
+#define NID_rc4				5
+#define OBJ_rc4				OBJ_rsadsi,3L,4L
+
+#define LN_rsaEncryption		"rsaEncryption"
+#define NID_rsaEncryption		6
+#define OBJ_rsaEncryption		OBJ_pkcs,1L,1L
+
+#define SN_md2WithRSAEncryption		"RSA-MD2"
+#define LN_md2WithRSAEncryption		"md2WithRSAEncryption"
+#define NID_md2WithRSAEncryption	7
+#define OBJ_md2WithRSAEncryption	OBJ_pkcs,1L,2L
+
+#define SN_md5WithRSAEncryption		"RSA-MD5"
+#define LN_md5WithRSAEncryption		"md5WithRSAEncryption"
+#define NID_md5WithRSAEncryption	8
+#define OBJ_md5WithRSAEncryption	OBJ_pkcs,1L,4L
+
+#define SN_pbeWithMD2AndDES_CBC		"PBE-MD2-DES"
+#define LN_pbeWithMD2AndDES_CBC		"pbeWithMD2AndDES-CBC"
+#define NID_pbeWithMD2AndDES_CBC	9
+#define OBJ_pbeWithMD2AndDES_CBC	OBJ_pkcs,5L,1L
+
+#define SN_pbeWithMD5AndDES_CBC		"PBE-MD5-DES"
+#define LN_pbeWithMD5AndDES_CBC		"pbeWithMD5AndDES-CBC"
+#define NID_pbeWithMD5AndDES_CBC	10
+#define OBJ_pbeWithMD5AndDES_CBC	OBJ_pkcs,5L,3L
+
+#define LN_X500				"X500"
+#define NID_X500			11
+#define OBJ_X500			2L,5L
+
+#define LN_X509				"X509"
+#define NID_X509			12
+#define OBJ_X509			OBJ_X500,4L
+
+#define SN_commonName			"CN"
+#define LN_commonName			"commonName"
+#define NID_commonName			13
+#define OBJ_commonName			OBJ_X509,3L
+
+#define SN_countryName			"C"
+#define LN_countryName			"countryName"
+#define NID_countryName			14
+#define OBJ_countryName			OBJ_X509,6L
+
+#define SN_localityName			"L"
+#define LN_localityName			"localityName"
+#define NID_localityName		15
+#define OBJ_localityName		OBJ_X509,7L
+
+/* Postal Address? PA */
+
+/* should be "ST" (rfc1327) but MS uses 'S' */
+#define SN_stateOrProvinceName		"ST"
+#define LN_stateOrProvinceName		"stateOrProvinceName"
+#define NID_stateOrProvinceName		16
+#define OBJ_stateOrProvinceName		OBJ_X509,8L
+
+#define SN_organizationName		"O"
+#define LN_organizationName		"organizationName"
+#define NID_organizationName		17
+#define OBJ_organizationName		OBJ_X509,10L
+
+#define SN_organizationalUnitName	"OU"
+#define LN_organizationalUnitName	"organizationalUnitName"
+#define NID_organizationalUnitName	18
+#define OBJ_organizationalUnitName	OBJ_X509,11L
+
+#define SN_rsa				"RSA"
+#define LN_rsa				"rsa"
+#define NID_rsa				19
+#define OBJ_rsa				OBJ_X500,8L,1L,1L
+
+#define LN_pkcs7			"pkcs7"
+#define NID_pkcs7			20
+#define OBJ_pkcs7			OBJ_pkcs,7L
+
+#define LN_pkcs7_data			"pkcs7-data"
+#define NID_pkcs7_data			21
+#define OBJ_pkcs7_data			OBJ_pkcs7,1L
+
+#define LN_pkcs7_signed			"pkcs7-signedData"
+#define NID_pkcs7_signed		22
+#define OBJ_pkcs7_signed		OBJ_pkcs7,2L
+
+#define LN_pkcs7_enveloped		"pkcs7-envelopedData"
+#define NID_pkcs7_enveloped		23
+#define OBJ_pkcs7_enveloped		OBJ_pkcs7,3L
+
+#define LN_pkcs7_signedAndEnveloped	"pkcs7-signedAndEnvelopedData"
+#define NID_pkcs7_signedAndEnveloped	24
+#define OBJ_pkcs7_signedAndEnveloped	OBJ_pkcs7,4L
+
+#define LN_pkcs7_digest			"pkcs7-digestData"
+#define NID_pkcs7_digest		25
+#define OBJ_pkcs7_digest		OBJ_pkcs7,5L
+
+#define LN_pkcs7_encrypted		"pkcs7-encryptedData"
+#define NID_pkcs7_encrypted		26
+#define OBJ_pkcs7_encrypted		OBJ_pkcs7,6L
+
+#define LN_pkcs3			"pkcs3"
+#define NID_pkcs3			27
+#define OBJ_pkcs3			OBJ_pkcs,3L
+
+#define LN_dhKeyAgreement		"dhKeyAgreement"
+#define NID_dhKeyAgreement		28
+#define OBJ_dhKeyAgreement		OBJ_pkcs3,1L
+
+#define SN_des_ecb			"DES-ECB"
+#define LN_des_ecb			"des-ecb"
+#define NID_des_ecb			29
+#define OBJ_des_ecb			OBJ_algorithm,6L
+
+#define SN_des_cfb64			"DES-CFB"
+#define LN_des_cfb64			"des-cfb"
+#define NID_des_cfb64			30
+/* IV + num */
+#define OBJ_des_cfb64			OBJ_algorithm,9L
+
+#define SN_des_cbc			"DES-CBC"
+#define LN_des_cbc			"des-cbc"
+#define NID_des_cbc			31
+/* IV */
+#define OBJ_des_cbc			OBJ_algorithm,7L
+
+#define SN_des_ede			"DES-EDE"
+#define LN_des_ede			"des-ede"
+#define NID_des_ede			32
+/* ?? */
+#define OBJ_des_ede			OBJ_algorithm,17L
+
+#define SN_des_ede3			"DES-EDE3"
+#define LN_des_ede3			"des-ede3"
+#define NID_des_ede3			33
+
+#define SN_idea_cbc			"IDEA-CBC"
+#define LN_idea_cbc			"idea-cbc"
+#define NID_idea_cbc			34
+#define OBJ_idea_cbc			1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L
+
+#define SN_idea_cfb64			"IDEA-CFB"
+#define LN_idea_cfb64			"idea-cfb"
+#define NID_idea_cfb64			35
+
+#define SN_idea_ecb			"IDEA-ECB"
+#define LN_idea_ecb			"idea-ecb"
+#define NID_idea_ecb			36
+
+#define SN_rc2_cbc			"RC2-CBC"
+#define LN_rc2_cbc			"rc2-cbc"
+#define NID_rc2_cbc			37
+#define OBJ_rc2_cbc			OBJ_rsadsi,3L,2L
+
+#define SN_rc2_ecb			"RC2-ECB"
+#define LN_rc2_ecb			"rc2-ecb"
+#define NID_rc2_ecb			38
+
+#define SN_rc2_cfb64			"RC2-CFB"
+#define LN_rc2_cfb64			"rc2-cfb"
+#define NID_rc2_cfb64			39
+
+#define SN_rc2_ofb64			"RC2-OFB"
+#define LN_rc2_ofb64			"rc2-ofb"
+#define NID_rc2_ofb64			40
+
+#define SN_sha				"SHA"
+#define LN_sha				"sha"
+#define NID_sha				41
+#define OBJ_sha				OBJ_algorithm,18L
+
+#define SN_shaWithRSAEncryption		"RSA-SHA"
+#define LN_shaWithRSAEncryption		"shaWithRSAEncryption"
+#define NID_shaWithRSAEncryption	42
+#define OBJ_shaWithRSAEncryption	OBJ_algorithm,15L
+
+#define SN_des_ede_cbc			"DES-EDE-CBC"
+#define LN_des_ede_cbc			"des-ede-cbc"
+#define NID_des_ede_cbc			43
+
+#define SN_des_ede3_cbc			"DES-EDE3-CBC"
+#define LN_des_ede3_cbc			"des-ede3-cbc"
+#define NID_des_ede3_cbc		44
+#define OBJ_des_ede3_cbc		OBJ_rsadsi,3L,7L
+
+#define SN_des_ofb64			"DES-OFB"
+#define LN_des_ofb64			"des-ofb"
+#define NID_des_ofb64			45
+#define OBJ_des_ofb64			OBJ_algorithm,8L
+
+#define SN_idea_ofb64			"IDEA-OFB"
+#define LN_idea_ofb64			"idea-ofb"
+#define NID_idea_ofb64			46
+
+#define LN_pkcs9			"pkcs9"
+#define NID_pkcs9			47
+#define OBJ_pkcs9			OBJ_pkcs,9L
+
+#define SN_pkcs9_emailAddress		"Email"
+#define LN_pkcs9_emailAddress		"emailAddress"
+#define NID_pkcs9_emailAddress		48
+#define OBJ_pkcs9_emailAddress		OBJ_pkcs9,1L
+
+#define LN_pkcs9_unstructuredName	"unstructuredName"
+#define NID_pkcs9_unstructuredName	49
+#define OBJ_pkcs9_unstructuredName	OBJ_pkcs9,2L
+
+#define LN_pkcs9_contentType		"contentType"
+#define NID_pkcs9_contentType		50
+#define OBJ_pkcs9_contentType		OBJ_pkcs9,3L
+
+#define LN_pkcs9_messageDigest		"messageDigest"
+#define NID_pkcs9_messageDigest		51
+#define OBJ_pkcs9_messageDigest		OBJ_pkcs9,4L
+
+#define LN_pkcs9_signingTime		"signingTime"
+#define NID_pkcs9_signingTime		52
+#define OBJ_pkcs9_signingTime		OBJ_pkcs9,5L
+
+#define LN_pkcs9_countersignature	"countersignature"
+#define NID_pkcs9_countersignature	53
+#define OBJ_pkcs9_countersignature	OBJ_pkcs9,6L
+
+#define LN_pkcs9_challengePassword	"challengePassword"
+#define NID_pkcs9_challengePassword	54
+#define OBJ_pkcs9_challengePassword	OBJ_pkcs9,7L
+
+#define LN_pkcs9_unstructuredAddress	"unstructuredAddress"
+#define NID_pkcs9_unstructuredAddress	55
+#define OBJ_pkcs9_unstructuredAddress	OBJ_pkcs9,8L
+
+#define LN_pkcs9_extCertAttributes	"extendedCertificateAttributes"
+#define NID_pkcs9_extCertAttributes	56
+#define OBJ_pkcs9_extCertAttributes	OBJ_pkcs9,9L
+
+#define SN_netscape			"Netscape"
+#define LN_netscape			"Netscape Communications Corp."
+#define NID_netscape			57
+#define OBJ_netscape			2L,16L,840L,1L,113730L
+
+#define SN_netscape_cert_extension	"nsCertExt"
+#define LN_netscape_cert_extension	"Netscape Certificate Extension"
+#define NID_netscape_cert_extension	58
+#define OBJ_netscape_cert_extension	OBJ_netscape,1L
+
+#define SN_netscape_data_type		"nsDataType"
+#define LN_netscape_data_type		"Netscape Data Type"
+#define NID_netscape_data_type		59
+#define OBJ_netscape_data_type		OBJ_netscape,2L
+
+#define SN_des_ede_cfb64		"DES-EDE-CFB"
+#define LN_des_ede_cfb64		"des-ede-cfb"
+#define NID_des_ede_cfb64		60
+
+#define SN_des_ede3_cfb64		"DES-EDE3-CFB"
+#define LN_des_ede3_cfb64		"des-ede3-cfb"
+#define NID_des_ede3_cfb64		61
+
+#define SN_des_ede_ofb64		"DES-EDE-OFB"
+#define LN_des_ede_ofb64		"des-ede-ofb"
+#define NID_des_ede_ofb64		62
+
+#define SN_des_ede3_ofb64		"DES-EDE3-OFB"
+#define LN_des_ede3_ofb64		"des-ede3-ofb"
+#define NID_des_ede3_ofb64		63
+
+/* I'm not sure about the object ID */
+#define SN_sha1				"SHA1"
+#define LN_sha1				"sha1"
+#define NID_sha1			64
+#define OBJ_sha1			OBJ_algorithm,26L
+/* 28 Jun 1996 - eay */
+/* #define OBJ_sha1			1L,3L,14L,2L,26L,05L <- wrong */
+
+#define SN_sha1WithRSAEncryption	"RSA-SHA1"
+#define LN_sha1WithRSAEncryption	"sha1WithRSAEncryption"
+#define NID_sha1WithRSAEncryption	65
+#define OBJ_sha1WithRSAEncryption	OBJ_pkcs,1L,5L
+
+#define SN_dsaWithSHA			"DSA-SHA"
+#define LN_dsaWithSHA			"dsaWithSHA"
+#define NID_dsaWithSHA			66
+#define OBJ_dsaWithSHA			OBJ_algorithm,13L
+
+#define SN_dsa_2			"DSA-old"
+#define LN_dsa_2			"dsaEncryption-old"
+#define NID_dsa_2			67
+#define OBJ_dsa_2			OBJ_algorithm,12L
+
+/* proposed by microsoft to RSA */
+#define SN_pbeWithSHA1AndRC2_CBC	"PBE-SHA1-RC2-64"
+#define LN_pbeWithSHA1AndRC2_CBC	"pbeWithSHA1AndRC2-CBC"
+#define NID_pbeWithSHA1AndRC2_CBC	68
+#define OBJ_pbeWithSHA1AndRC2_CBC	OBJ_pkcs,5L,11L 
+
+/* proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now
+ * defined explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something
+ * completely different.
+ */
+#define LN_id_pbkdf2			"PBKDF2"
+#define NID_id_pbkdf2			69
+#define OBJ_id_pbkdf2			OBJ_pkcs,5L,12L 
+
+#define SN_dsaWithSHA1_2		"DSA-SHA1-old"
+#define LN_dsaWithSHA1_2		"dsaWithSHA1-old"
+#define NID_dsaWithSHA1_2		70
+/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */
+#define OBJ_dsaWithSHA1_2		OBJ_algorithm,27L
+
+#define SN_netscape_cert_type		"nsCertType"
+#define LN_netscape_cert_type		"Netscape Cert Type"
+#define NID_netscape_cert_type		71
+#define OBJ_netscape_cert_type		OBJ_netscape_cert_extension,1L
+
+#define SN_netscape_base_url		"nsBaseUrl"
+#define LN_netscape_base_url		"Netscape Base Url"
+#define NID_netscape_base_url		72
+#define OBJ_netscape_base_url		OBJ_netscape_cert_extension,2L
+
+#define SN_netscape_revocation_url	"nsRevocationUrl"
+#define LN_netscape_revocation_url	"Netscape Revocation Url"
+#define NID_netscape_revocation_url	73
+#define OBJ_netscape_revocation_url	OBJ_netscape_cert_extension,3L
+
+#define SN_netscape_ca_revocation_url	"nsCaRevocationUrl"
+#define LN_netscape_ca_revocation_url	"Netscape CA Revocation Url"
+#define NID_netscape_ca_revocation_url	74
+#define OBJ_netscape_ca_revocation_url	OBJ_netscape_cert_extension,4L
+
+#define SN_netscape_renewal_url		"nsRenewalUrl"
+#define LN_netscape_renewal_url		"Netscape Renewal Url"
+#define NID_netscape_renewal_url	75
+#define OBJ_netscape_renewal_url	OBJ_netscape_cert_extension,7L
+
+#define SN_netscape_ca_policy_url	"nsCaPolicyUrl"
+#define LN_netscape_ca_policy_url	"Netscape CA Policy Url"
+#define NID_netscape_ca_policy_url	76
+#define OBJ_netscape_ca_policy_url	OBJ_netscape_cert_extension,8L
+
+#define SN_netscape_ssl_server_name	"nsSslServerName"
+#define LN_netscape_ssl_server_name	"Netscape SSL Server Name"
+#define NID_netscape_ssl_server_name	77
+#define OBJ_netscape_ssl_server_name	OBJ_netscape_cert_extension,12L
+
+#define SN_netscape_comment		"nsComment"
+#define LN_netscape_comment		"Netscape Comment"
+#define NID_netscape_comment		78
+#define OBJ_netscape_comment		OBJ_netscape_cert_extension,13L
+
+#define SN_netscape_cert_sequence	"nsCertSequence"
+#define LN_netscape_cert_sequence	"Netscape Certificate Sequence"
+#define NID_netscape_cert_sequence	79
+#define OBJ_netscape_cert_sequence	OBJ_netscape_data_type,5L
+
+#define SN_desx_cbc			"DESX-CBC"
+#define LN_desx_cbc			"desx-cbc"
+#define NID_desx_cbc			80
+
+#define SN_id_ce			"id-ce"
+#define NID_id_ce			81
+#define OBJ_id_ce			2L,5L,29L
+
+#define SN_subject_key_identifier	"subjectKeyIdentifier"
+#define LN_subject_key_identifier	"X509v3 Subject Key Identifier"
+#define NID_subject_key_identifier	82
+#define OBJ_subject_key_identifier	OBJ_id_ce,14L
+
+#define SN_key_usage			"keyUsage"
+#define LN_key_usage			"X509v3 Key Usage"
+#define NID_key_usage			83
+#define OBJ_key_usage			OBJ_id_ce,15L
+
+#define SN_private_key_usage_period	"privateKeyUsagePeriod"
+#define LN_private_key_usage_period	"X509v3 Private Key Usage Period"
+#define NID_private_key_usage_period	84
+#define OBJ_private_key_usage_period	OBJ_id_ce,16L
+
+#define SN_subject_alt_name		"subjectAltName"
+#define LN_subject_alt_name		"X509v3 Subject Alternative Name"
+#define NID_subject_alt_name		85
+#define OBJ_subject_alt_name		OBJ_id_ce,17L
+
+#define SN_issuer_alt_name		"issuerAltName"
+#define LN_issuer_alt_name		"X509v3 Issuer Alternative Name"
+#define NID_issuer_alt_name		86
+#define OBJ_issuer_alt_name		OBJ_id_ce,18L
+
+#define SN_basic_constraints		"basicConstraints"
+#define LN_basic_constraints		"X509v3 Basic Constraints"
+#define NID_basic_constraints		87
+#define OBJ_basic_constraints		OBJ_id_ce,19L
+
+#define SN_crl_number			"crlNumber"
+#define LN_crl_number			"X509v3 CRL Number"
+#define NID_crl_number			88
+#define OBJ_crl_number			OBJ_id_ce,20L
+
+#define SN_certificate_policies		"certificatePolicies"
+#define LN_certificate_policies		"X509v3 Certificate Policies"
+#define NID_certificate_policies	89
+#define OBJ_certificate_policies	OBJ_id_ce,32L
+
+#define SN_authority_key_identifier	"authorityKeyIdentifier"
+#define LN_authority_key_identifier	"X509v3 Authority Key Identifier"
+#define NID_authority_key_identifier	90
+#define OBJ_authority_key_identifier	OBJ_id_ce,35L
+
+#define SN_bf_cbc			"BF-CBC"
+#define LN_bf_cbc			"bf-cbc"
+#define NID_bf_cbc			91
+#define OBJ_bf_cbc			1L,3L,6L,1L,4L,1L,3029L,1L,2L
+
+#define SN_bf_ecb			"BF-ECB"
+#define LN_bf_ecb			"bf-ecb"
+#define NID_bf_ecb			92
+
+#define SN_bf_cfb64			"BF-CFB"
+#define LN_bf_cfb64			"bf-cfb"
+#define NID_bf_cfb64			93
+
+#define SN_bf_ofb64			"BF-OFB"
+#define LN_bf_ofb64			"bf-ofb"
+#define NID_bf_ofb64			94
+
+#define SN_mdc2				"MDC2"
+#define LN_mdc2				"mdc2"
+#define NID_mdc2			95
+#define OBJ_mdc2			2L,5L,8L,3L,101L
+/* An alternative?			1L,3L,14L,3L,2L,19L */
+
+#define SN_mdc2WithRSA			"RSA-MDC2"
+#define LN_mdc2WithRSA			"mdc2withRSA"
+#define NID_mdc2WithRSA			96
+#define OBJ_mdc2WithRSA			2L,5L,8L,3L,100L
+
+#define SN_rc4_40			"RC4-40"
+#define LN_rc4_40			"rc4-40"
+#define NID_rc4_40			97
+
+#define SN_rc2_40_cbc			"RC2-40-CBC"
+#define LN_rc2_40_cbc			"rc2-40-cbc"
+#define NID_rc2_40_cbc			98
+
+#define SN_givenName			"G"
+#define LN_givenName			"givenName"
+#define NID_givenName			99
+#define OBJ_givenName			OBJ_X509,42L
+
+#define SN_surname			"S"
+#define LN_surname			"surname"
+#define NID_surname			100
+#define OBJ_surname			OBJ_X509,4L
+
+#define SN_initials			"I"
+#define LN_initials			"initials"
+#define NID_initials			101
+#define OBJ_initials			OBJ_X509,43L
+
+#define SN_uniqueIdentifier		"UID"
+#define LN_uniqueIdentifier		"uniqueIdentifier"
+#define NID_uniqueIdentifier		102
+#define OBJ_uniqueIdentifier		OBJ_X509,45L
+
+#define SN_crl_distribution_points	"crlDistributionPoints"
+#define LN_crl_distribution_points	"X509v3 CRL Distribution Points"
+#define NID_crl_distribution_points	103
+#define OBJ_crl_distribution_points	OBJ_id_ce,31L
+
+#define SN_md5WithRSA			"RSA-NP-MD5"
+#define LN_md5WithRSA			"md5WithRSA"
+#define NID_md5WithRSA			104
+#define OBJ_md5WithRSA			OBJ_algorithm,3L
+
+#define SN_serialNumber			"SN"
+#define LN_serialNumber			"serialNumber"
+#define NID_serialNumber		105
+#define OBJ_serialNumber		OBJ_X509,5L
+
+#define SN_title			"T"
+#define LN_title			"title"
+#define NID_title			106
+#define OBJ_title			OBJ_X509,12L
+
+#define SN_description			"D"
+#define LN_description			"description"
+#define NID_description			107
+#define OBJ_description			OBJ_X509,13L
+
+/* CAST5 is CAST-128, I'm just sticking with the documentation */
+#define SN_cast5_cbc			"CAST5-CBC"
+#define LN_cast5_cbc			"cast5-cbc"
+#define NID_cast5_cbc			108
+#define OBJ_cast5_cbc			1L,2L,840L,113533L,7L,66L,10L
+
+#define SN_cast5_ecb			"CAST5-ECB"
+#define LN_cast5_ecb			"cast5-ecb"
+#define NID_cast5_ecb			109
+
+#define SN_cast5_cfb64			"CAST5-CFB"
+#define LN_cast5_cfb64			"cast5-cfb"
+#define NID_cast5_cfb64			110
+
+#define SN_cast5_ofb64			"CAST5-OFB"
+#define LN_cast5_ofb64			"cast5-ofb"
+#define NID_cast5_ofb64			111
+
+#define LN_pbeWithMD5AndCast5_CBC	"pbeWithMD5AndCast5CBC"
+#define NID_pbeWithMD5AndCast5_CBC	112
+#define OBJ_pbeWithMD5AndCast5_CBC	1L,2L,840L,113533L,7L,66L,12L
+
+/* This is one sun will soon be using :-(
+ * id-dsa-with-sha1 ID  ::= {
+ *   iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 }
+ */
+#define SN_dsaWithSHA1			"DSA-SHA1"
+#define LN_dsaWithSHA1			"dsaWithSHA1"
+#define NID_dsaWithSHA1			113
+#define OBJ_dsaWithSHA1			1L,2L,840L,10040L,4L,3L
+
+#define NID_md5_sha1			114
+#define SN_md5_sha1			"MD5-SHA1"
+#define LN_md5_sha1			"md5-sha1"
+
+#define SN_sha1WithRSA			"RSA-SHA1-2"
+#define LN_sha1WithRSA			"sha1WithRSA"
+#define NID_sha1WithRSA			115
+#define OBJ_sha1WithRSA			OBJ_algorithm,29L
+
+#define SN_dsa				"DSA"
+#define LN_dsa				"dsaEncryption"
+#define NID_dsa				116
+#define OBJ_dsa				1L,2L,840L,10040L,4L,1L
+
+#define SN_ripemd160			"RIPEMD160"
+#define LN_ripemd160			"ripemd160"
+#define NID_ripemd160			117
+#define OBJ_ripemd160			1L,3L,36L,3L,2L,1L
+
+/* The name should actually be rsaSignatureWithripemd160, but I'm going
+ * to continue using the convention I'm using with the other ciphers */
+#define SN_ripemd160WithRSA		"RSA-RIPEMD160"
+#define LN_ripemd160WithRSA		"ripemd160WithRSA"
+#define NID_ripemd160WithRSA		119
+#define OBJ_ripemd160WithRSA		1L,3L,36L,3L,3L,1L,2L
+
+/* Taken from rfc2040
+ *  RC5_CBC_Parameters ::= SEQUENCE {
+ *	version           INTEGER (v1_0(16)),
+ *	rounds            INTEGER (8..127),
+ *	blockSizeInBits   INTEGER (64, 128),
+ *	iv                OCTET STRING OPTIONAL
+ *	}
+ */
+#define SN_rc5_cbc			"RC5-CBC"
+#define LN_rc5_cbc			"rc5-cbc"
+#define NID_rc5_cbc			120
+#define OBJ_rc5_cbc			OBJ_rsadsi,3L,8L
+
+#define SN_rc5_ecb			"RC5-ECB"
+#define LN_rc5_ecb			"rc5-ecb"
+#define NID_rc5_ecb			121
+
+#define SN_rc5_cfb64			"RC5-CFB"
+#define LN_rc5_cfb64			"rc5-cfb"
+#define NID_rc5_cfb64			122
+
+#define SN_rc5_ofb64			"RC5-OFB"
+#define LN_rc5_ofb64			"rc5-ofb"
+#define NID_rc5_ofb64			123
+
+#define SN_rle_compression		"RLE"
+#define LN_rle_compression		"run length compression"
+#define NID_rle_compression		124
+#define OBJ_rle_compression		1L,1L,1L,1L,666L,1L
+
+#define SN_zlib_compression		"ZLIB"
+#define LN_zlib_compression		"zlib compression"
+#define NID_zlib_compression		125
+#define OBJ_zlib_compression		1L,1L,1L,1L,666L,2L
+
+#define SN_ext_key_usage		"extendedKeyUsage"
+#define LN_ext_key_usage		"X509v3 Extended Key Usage"
+#define NID_ext_key_usage		126
+#define OBJ_ext_key_usage		OBJ_id_ce,37
+
+#define SN_id_pkix			"PKIX"
+#define NID_id_pkix			127
+#define OBJ_id_pkix			1L,3L,6L,1L,5L,5L,7L
+
+#define SN_id_kp			"id-kp"
+#define NID_id_kp			128
+#define OBJ_id_kp			OBJ_id_pkix,3L
+
+/* PKIX extended key usage OIDs */
+
+#define SN_server_auth			"serverAuth"
+#define LN_server_auth			"TLS Web Server Authentication"
+#define NID_server_auth			129
+#define OBJ_server_auth			OBJ_id_kp,1L
+
+#define SN_client_auth			"clientAuth"
+#define LN_client_auth			"TLS Web Client Authentication"
+#define NID_client_auth			130
+#define OBJ_client_auth			OBJ_id_kp,2L
+
+#define SN_code_sign			"codeSigning"
+#define LN_code_sign			"Code Signing"
+#define NID_code_sign			131
+#define OBJ_code_sign			OBJ_id_kp,3L
+
+#define SN_email_protect		"emailProtection"
+#define LN_email_protect		"E-mail Protection"
+#define NID_email_protect		132
+#define OBJ_email_protect		OBJ_id_kp,4L
+
+#define SN_time_stamp			"timeStamping"
+#define LN_time_stamp			"Time Stamping"
+#define NID_time_stamp			133
+#define OBJ_time_stamp			OBJ_id_kp,8L
+
+/* Additional extended key usage OIDs: Microsoft */
+
+#define SN_ms_code_ind			"msCodeInd"
+#define LN_ms_code_ind			"Microsoft Individual Code Signing"
+#define NID_ms_code_ind			134
+#define OBJ_ms_code_ind			1L,3L,6L,1L,4L,1L,311L,2L,1L,21L
+
+#define SN_ms_code_com			"msCodeCom"
+#define LN_ms_code_com			"Microsoft Commercial Code Signing"
+#define NID_ms_code_com			135
+#define OBJ_ms_code_com			1L,3L,6L,1L,4L,1L,311L,2L,1L,22L
+
+#define SN_ms_ctl_sign			"msCTLSign"
+#define LN_ms_ctl_sign			"Microsoft Trust List Signing"
+#define NID_ms_ctl_sign			136
+#define OBJ_ms_ctl_sign			1L,3L,6L,1L,4L,1L,311L,10L,3L,1L
+
+#define SN_ms_sgc			"msSGC"
+#define LN_ms_sgc			"Microsoft Server Gated Crypto"
+#define NID_ms_sgc			137
+#define OBJ_ms_sgc			1L,3L,6L,1L,4L,1L,311L,10L,3L,3L
+
+#define SN_ms_efs			"msEFS"
+#define LN_ms_efs			"Microsoft Encrypted File System"
+#define NID_ms_efs			138
+#define OBJ_ms_efs			1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
+
+/* Additional usage: Netscape */
+
+#define SN_ns_sgc			"nsSGC"
+#define LN_ns_sgc			"Netscape Server Gated Crypto"
+#define NID_ns_sgc			139
+#define OBJ_ns_sgc			OBJ_netscape,4L,1L
+
+#define SN_delta_crl			"deltaCRL"
+#define LN_delta_crl			"X509v3 Delta CRL Indicator"
+#define NID_delta_crl			140
+#define OBJ_delta_crl			OBJ_id_ce,27L
+
+#define SN_crl_reason			"CRLReason"
+#define LN_crl_reason			"CRL Reason Code"
+#define NID_crl_reason			141
+#define OBJ_crl_reason			OBJ_id_ce,21L
+
+#define SN_invalidity_date		"invalidityDate"
+#define LN_invalidity_date		"Invalidity Date"
+#define NID_invalidity_date		142
+#define OBJ_invalidity_date		OBJ_id_ce,24L
+
+#define SN_sxnet			"SXNetID"
+#define LN_sxnet			"Strong Extranet ID"
+#define NID_sxnet			143
+#define OBJ_sxnet			1L,3L,101L,1L,4L,1L
+
+/* PKCS12 and related OBJECT IDENTIFIERS */
+
+#define OBJ_pkcs12			OBJ_pkcs,12L
+#define OBJ_pkcs12_pbeids		OBJ_pkcs12, 1
+
+#define SN_pbe_WithSHA1And128BitRC4	"PBE-SHA1-RC4-128"
+#define LN_pbe_WithSHA1And128BitRC4	"pbeWithSHA1And128BitRC4"
+#define NID_pbe_WithSHA1And128BitRC4	144
+#define OBJ_pbe_WithSHA1And128BitRC4	OBJ_pkcs12_pbeids, 1L
+
+#define SN_pbe_WithSHA1And40BitRC4	"PBE-SHA1-RC4-40"
+#define LN_pbe_WithSHA1And40BitRC4	"pbeWithSHA1And40BitRC4"
+#define NID_pbe_WithSHA1And40BitRC4	145
+#define OBJ_pbe_WithSHA1And40BitRC4	OBJ_pkcs12_pbeids, 2L
+
+#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC	"PBE-SHA1-3DES"
+#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC	"pbeWithSHA1And3-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC	146
+#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 3L
+
+#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC	"PBE-SHA1-2DES"
+#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC	"pbeWithSHA1And2-KeyTripleDES-CBC"
+#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC	147
+#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC	OBJ_pkcs12_pbeids, 4L
+
+#define SN_pbe_WithSHA1And128BitRC2_CBC		"PBE-SHA1-RC2-128"
+#define LN_pbe_WithSHA1And128BitRC2_CBC		"pbeWithSHA1And128BitRC2-CBC"
+#define NID_pbe_WithSHA1And128BitRC2_CBC	148
+#define OBJ_pbe_WithSHA1And128BitRC2_CBC	OBJ_pkcs12_pbeids, 5L
+
+#define SN_pbe_WithSHA1And40BitRC2_CBC	"PBE-SHA1-RC2-40"
+#define LN_pbe_WithSHA1And40BitRC2_CBC	"pbeWithSHA1And40BitRC2-CBC"
+#define NID_pbe_WithSHA1And40BitRC2_CBC	149
+#define OBJ_pbe_WithSHA1And40BitRC2_CBC	OBJ_pkcs12_pbeids, 6L
+
+#define OBJ_pkcs12_Version1	OBJ_pkcs12, 10L
+
+#define OBJ_pkcs12_BagIds	OBJ_pkcs12_Version1, 1L
+
+#define LN_keyBag		"keyBag"
+#define NID_keyBag		150
+#define OBJ_keyBag		OBJ_pkcs12_BagIds, 1L
+
+#define LN_pkcs8ShroudedKeyBag	"pkcs8ShroudedKeyBag"
+#define NID_pkcs8ShroudedKeyBag	151
+#define OBJ_pkcs8ShroudedKeyBag	OBJ_pkcs12_BagIds, 2L
+
+#define LN_certBag		"certBag"
+#define NID_certBag		152
+#define OBJ_certBag		OBJ_pkcs12_BagIds, 3L
+
+#define LN_crlBag		"crlBag"
+#define NID_crlBag		153
+#define OBJ_crlBag		OBJ_pkcs12_BagIds, 4L
+
+#define LN_secretBag		"secretBag"
+#define NID_secretBag		154
+#define OBJ_secretBag		OBJ_pkcs12_BagIds, 5L
+
+#define LN_safeContentsBag	"safeContentsBag"
+#define NID_safeContentsBag	155
+#define OBJ_safeContentsBag	OBJ_pkcs12_BagIds, 6L
+
+#define LN_friendlyName		"friendlyName"
+#define	NID_friendlyName	156
+#define OBJ_friendlyName	OBJ_pkcs9, 20L
+
+#define LN_localKeyID		"localKeyID"
+#define	NID_localKeyID		157
+#define OBJ_localKeyID		OBJ_pkcs9, 21L
+
+#define OBJ_certTypes		OBJ_pkcs9, 22L
+
+#define LN_x509Certificate	"x509Certificate"
+#define	NID_x509Certificate	158
+#define OBJ_x509Certificate	OBJ_certTypes, 1L
+
+#define LN_sdsiCertificate	"sdsiCertificate"
+#define	NID_sdsiCertificate	159
+#define OBJ_sdsiCertificate	OBJ_certTypes, 2L
+
+#define OBJ_crlTypes		OBJ_pkcs9, 23L
+
+#define LN_x509Crl		"x509Crl"
+#define	NID_x509Crl		160
+#define OBJ_x509Crl		OBJ_crlTypes, 1L
+
+/* PKCS#5 v2 OIDs */
+
+#define LN_pbes2		"PBES2"
+#define NID_pbes2		161
+#define OBJ_pbes2		OBJ_pkcs,5L,13L
+
+#define LN_pbmac1		"PBMAC1"
+#define NID_pbmac1		162
+#define OBJ_pbmac1		OBJ_pkcs,5L,14L
+
+#define LN_hmacWithSHA1		"hmacWithSHA1"
+#define NID_hmacWithSHA1	163
+#define OBJ_hmacWithSHA1	OBJ_rsadsi,2L,7L
+
+/* Policy Qualifier Ids */
+
+#define LN_id_qt_cps		"Policy Qualifier CPS"
+#define SN_id_qt_cps		"id-qt-cps"
+#define NID_id_qt_cps		164
+#define OBJ_id_qt_cps		OBJ_id_pkix,2L,1L
+
+#define LN_id_qt_unotice	"Policy Qualifier User Notice"
+#define SN_id_qt_unotice	"id-qt-unotice"
+#define NID_id_qt_unotice	165
+#define OBJ_id_qt_unotice	OBJ_id_pkix,2L,2L
+
+#define SN_rc2_64_cbc			"RC2-64-CBC"
+#define LN_rc2_64_cbc			"rc2-64-cbc"
+#define NID_rc2_64_cbc			166
+
+#define SN_SMIMECapabilities		"SMIME-CAPS"
+#define LN_SMIMECapabilities		"S/MIME Capabilities"
+#define NID_SMIMECapabilities		167
+#define OBJ_SMIMECapabilities		OBJ_pkcs9,15L
+
+#define SN_pbeWithMD2AndRC2_CBC		"PBE-MD2-RC2-64"
+#define LN_pbeWithMD2AndRC2_CBC		"pbeWithMD2AndRC2-CBC"
+#define NID_pbeWithMD2AndRC2_CBC	168
+#define OBJ_pbeWithMD2AndRC2_CBC	OBJ_pkcs,5L,4L
+
+#define SN_pbeWithMD5AndRC2_CBC		"PBE-MD5-RC2-64"
+#define LN_pbeWithMD5AndRC2_CBC		"pbeWithMD5AndRC2-CBC"
+#define NID_pbeWithMD5AndRC2_CBC	169
+#define OBJ_pbeWithMD5AndRC2_CBC	OBJ_pkcs,5L,6L
+
+#define SN_pbeWithSHA1AndDES_CBC	"PBE-SHA1-DES"
+#define LN_pbeWithSHA1AndDES_CBC	"pbeWithSHA1AndDES-CBC"
+#define NID_pbeWithSHA1AndDES_CBC	170
+#define OBJ_pbeWithSHA1AndDES_CBC	OBJ_pkcs,5L,10L
+
+/* Extension request OIDs */
+
+#define LN_ms_ext_req			"Microsoft Extension Request"
+#define SN_ms_ext_req			"msExtReq"
+#define NID_ms_ext_req			171
+#define OBJ_ms_ext_req			1L,3L,6L,1L,4L,1L,311L,2L,1L,14L
+
+#define LN_ext_req			"Extension Request"
+#define SN_ext_req			"extReq"
+#define NID_ext_req			172
+#define OBJ_ext_req			OBJ_pkcs9,14L
+
+#define SN_name				"name"
+#define LN_name				"name"
+#define NID_name			173
+#define OBJ_name			OBJ_X509,41L
+
+#define SN_dnQualifier			"dnQualifier"
+#define LN_dnQualifier			"dnQualifier"
+#define NID_dnQualifier			174
+#define OBJ_dnQualifier			OBJ_X509,46L
+
+#define SN_id_pe			"id-pe"
+#define NID_id_pe			175
+#define OBJ_id_pe			OBJ_id_pkix,1L
+
+#define SN_id_ad			"id-ad"
+#define NID_id_ad			176
+#define OBJ_id_ad			OBJ_id_pkix,48L
+
+#define SN_info_access			"authorityInfoAccess"
+#define LN_info_access			"Authority Information Access"
+#define NID_info_access			177
+#define OBJ_info_access			OBJ_id_pe,1L
+
+#define SN_ad_OCSP			"OCSP"
+#define LN_ad_OCSP			"OCSP"
+#define NID_ad_OCSP			178
+#define OBJ_ad_OCSP			OBJ_id_ad,1L
+
+#define SN_ad_ca_issuers		"caIssuers"
+#define LN_ad_ca_issuers		"CA Issuers"
+#define NID_ad_ca_issuers		179
+#define OBJ_ad_ca_issuers		OBJ_id_ad,2L
+
+#define SN_OCSP_sign			"OCSPSigning"
+#define LN_OCSP_sign			"OCSP Signing"
+#define NID_OCSP_sign			180
+#define OBJ_OCSP_sign			OBJ_id_kp,9L
+#endif /* USE_OBJ_MAC */
+
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+
+#define	OBJ_NAME_TYPE_UNDEF		0x00
+#define	OBJ_NAME_TYPE_MD_METH		0x01
+#define	OBJ_NAME_TYPE_CIPHER_METH	0x02
+#define	OBJ_NAME_TYPE_PKEY_METH		0x03
+#define	OBJ_NAME_TYPE_COMP_METH		0x04
+#define	OBJ_NAME_TYPE_NUM		0x05
+
+#define	OBJ_NAME_ALIAS			0x8000
+
+#define OBJ_BSEARCH_VALUE_ON_NOMATCH		0x01
+#define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH	0x02
+
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct obj_name_st
+	{
+	int type;
+	int alias;
+	const char *name;
+	const char *data;
+	} OBJ_NAME;
+
+#define		OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c)
+
+
+int OBJ_NAME_init(void);
+int OBJ_NAME_new_index(unsigned long (*hash_func)(const char *),
+		       int (*cmp_func)(const char *, const char *),
+		       void (*free_func)(const char *, int, const char *));
+const char *OBJ_NAME_get(const char *name,int type);
+int OBJ_NAME_add(const char *name,int type,const char *data);
+int OBJ_NAME_remove(const char *name,int type);
+void OBJ_NAME_cleanup(int type); /* -1 for everything */
+void OBJ_NAME_do_all(int type,void (*fn)(const OBJ_NAME *,void *arg),
+		     void *arg);
+void OBJ_NAME_do_all_sorted(int type,void (*fn)(const OBJ_NAME *,void *arg),
+			    void *arg);
+
+ASN1_OBJECT *	OBJ_dup(const ASN1_OBJECT *o);
+ASN1_OBJECT *	OBJ_nid2obj(int n);
+const char *	OBJ_nid2ln(int n);
+const char *	OBJ_nid2sn(int n);
+int		OBJ_obj2nid(const ASN1_OBJECT *o);
+ASN1_OBJECT *	OBJ_txt2obj(const char *s, int no_name);
+int	OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name);
+int		OBJ_txt2nid(const char *s);
+int		OBJ_ln2nid(const char *s);
+int		OBJ_sn2nid(const char *s);
+int		OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
+const char *	OBJ_bsearch(const char *key,const char *base,int num,int size,
+	int (*cmp)(const void *, const void *));
+const char *	OBJ_bsearch_ex(const char *key,const char *base,int num,
+	int size, int (*cmp)(const void *, const void *), int flags);
+
+int		OBJ_new_nid(int num);
+int		OBJ_add_object(const ASN1_OBJECT *obj);
+int		OBJ_create(const char *oid,const char *sn,const char *ln);
+void		OBJ_cleanup(void );
+int		OBJ_create_objects(BIO *in);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_OBJ_strings(void);
+
+/* Error codes for the OBJ functions. */
+
+/* Function codes. */
+#define OBJ_F_OBJ_ADD_OBJECT				 105
+#define OBJ_F_OBJ_CREATE				 100
+#define OBJ_F_OBJ_DUP					 101
+#define OBJ_F_OBJ_NAME_NEW_INDEX			 106
+#define OBJ_F_OBJ_NID2LN				 102
+#define OBJ_F_OBJ_NID2OBJ				 103
+#define OBJ_F_OBJ_NID2SN				 104
+
+/* Reason codes. */
+#define OBJ_R_MALLOC_FAILURE				 100
+#define OBJ_R_UNKNOWN_NID				 101
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ocsp.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ocsp.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ocsp.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,614 @@
+/* ocsp.h */
+/* Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
+ * project. */
+
+/* History:
+   This file was transfered to Richard Levitte from CertCo by Kathy
+   Weinhold in mid-spring 2000 to be included in OpenSSL or released
+   as a patch kit. */
+
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_OCSP_H
+#define HEADER_OCSP_H
+
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/safestack.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Various flags and values */
+
+#define OCSP_DEFAULT_NONCE_LENGTH	16
+
+#define OCSP_NOCERTS			0x1
+#define OCSP_NOINTERN			0x2
+#define OCSP_NOSIGS			0x4
+#define OCSP_NOCHAIN			0x8
+#define OCSP_NOVERIFY			0x10
+#define OCSP_NOEXPLICIT			0x20
+#define OCSP_NOCASIGN			0x40
+#define OCSP_NODELEGATED		0x80
+#define OCSP_NOCHECKS			0x100
+#define OCSP_TRUSTOTHER			0x200
+#define OCSP_RESPID_KEY			0x400
+#define OCSP_NOTIME			0x800
+
+/*   CertID ::= SEQUENCE {
+ *       hashAlgorithm            AlgorithmIdentifier,
+ *       issuerNameHash     OCTET STRING, -- Hash of Issuer's DN
+ *       issuerKeyHash      OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields)
+ *       serialNumber       CertificateSerialNumber }
+ */
+typedef struct ocsp_cert_id_st
+	{
+	X509_ALGOR *hashAlgorithm;
+	ASN1_OCTET_STRING *issuerNameHash;
+	ASN1_OCTET_STRING *issuerKeyHash;
+	ASN1_INTEGER *serialNumber;
+	} OCSP_CERTID;
+
+DECLARE_STACK_OF(OCSP_CERTID)
+
+/*   Request ::=     SEQUENCE {
+ *       reqCert                    CertID,
+ *       singleRequestExtensions    [0] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_one_request_st
+	{
+	OCSP_CERTID *reqCert;
+	STACK_OF(X509_EXTENSION) *singleRequestExtensions;
+	} OCSP_ONEREQ;
+
+DECLARE_STACK_OF(OCSP_ONEREQ)
+DECLARE_ASN1_SET_OF(OCSP_ONEREQ)
+
+
+/*   TBSRequest      ::=     SEQUENCE {
+ *       version             [0] EXPLICIT Version DEFAULT v1,
+ *       requestorName       [1] EXPLICIT GeneralName OPTIONAL,
+ *       requestList             SEQUENCE OF Request,
+ *       requestExtensions   [2] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_req_info_st
+	{
+	ASN1_INTEGER *version;
+	GENERAL_NAME *requestorName;
+	STACK_OF(OCSP_ONEREQ) *requestList;
+	STACK_OF(X509_EXTENSION) *requestExtensions;
+	} OCSP_REQINFO;
+
+/*   Signature       ::=     SEQUENCE {
+ *       signatureAlgorithm   AlgorithmIdentifier,
+ *       signature            BIT STRING,
+ *       certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+typedef struct ocsp_signature_st
+	{
+	X509_ALGOR *signatureAlgorithm;
+	ASN1_BIT_STRING *signature;
+	STACK_OF(X509) *certs;
+	} OCSP_SIGNATURE;
+
+/*   OCSPRequest     ::=     SEQUENCE {
+ *       tbsRequest                  TBSRequest,
+ *       optionalSignature   [0]     EXPLICIT Signature OPTIONAL }
+ */
+typedef struct ocsp_request_st
+	{
+	OCSP_REQINFO *tbsRequest;
+	OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */
+	} OCSP_REQUEST;
+
+/*   OCSPResponseStatus ::= ENUMERATED {
+ *       successful            (0),      --Response has valid confirmations
+ *       malformedRequest      (1),      --Illegal confirmation request
+ *       internalError         (2),      --Internal error in issuer
+ *       tryLater              (3),      --Try again later
+ *                                       --(4) is not used
+ *       sigRequired           (5),      --Must sign the request
+ *       unauthorized          (6)       --Request unauthorized
+ *   }
+ */
+#define OCSP_RESPONSE_STATUS_SUCCESSFUL          0
+#define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST     1
+#define OCSP_RESPONSE_STATUS_INTERNALERROR        2
+#define OCSP_RESPONSE_STATUS_TRYLATER             3
+#define OCSP_RESPONSE_STATUS_SIGREQUIRED          5
+#define OCSP_RESPONSE_STATUS_UNAUTHORIZED         6
+
+/*   ResponseBytes ::=       SEQUENCE {
+ *       responseType   OBJECT IDENTIFIER,
+ *       response       OCTET STRING }
+ */
+typedef struct ocsp_resp_bytes_st
+	{
+	ASN1_OBJECT *responseType;
+	ASN1_OCTET_STRING *response;
+	} OCSP_RESPBYTES;
+
+/*   OCSPResponse ::= SEQUENCE {
+ *      responseStatus         OCSPResponseStatus,
+ *      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL }
+ */
+typedef struct ocsp_response_st
+	{
+	ASN1_ENUMERATED *responseStatus;
+	OCSP_RESPBYTES  *responseBytes;
+	} OCSP_RESPONSE;
+
+/*   ResponderID ::= CHOICE {
+ *      byName   [1] Name,
+ *      byKey    [2] KeyHash }
+ */
+#define V_OCSP_RESPID_NAME 0
+#define V_OCSP_RESPID_KEY  1
+typedef struct ocsp_responder_id_st
+	{
+	int type;
+	union   {
+		X509_NAME* byName;
+        	ASN1_OCTET_STRING *byKey;
+		} value;
+	} OCSP_RESPID;
+/*   KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key
+ *                            --(excluding the tag and length fields)
+ */
+
+/*   RevokedInfo ::= SEQUENCE {
+ *       revocationTime              GeneralizedTime,
+ *       revocationReason    [0]     EXPLICIT CRLReason OPTIONAL }
+ */
+typedef struct ocsp_revoked_info_st
+	{
+	ASN1_GENERALIZEDTIME *revocationTime;
+	ASN1_ENUMERATED *revocationReason;
+	} OCSP_REVOKEDINFO;
+
+/*   CertStatus ::= CHOICE {
+ *       good                [0]     IMPLICIT NULL,
+ *       revoked             [1]     IMPLICIT RevokedInfo,
+ *       unknown             [2]     IMPLICIT UnknownInfo }
+ */
+#define V_OCSP_CERTSTATUS_GOOD    0
+#define V_OCSP_CERTSTATUS_REVOKED 1
+#define V_OCSP_CERTSTATUS_UNKNOWN 2
+typedef struct ocsp_cert_status_st
+	{
+	int type;
+	union	{
+		ASN1_NULL *good;
+		OCSP_REVOKEDINFO *revoked;
+		ASN1_NULL *unknown;
+		} value;
+	} OCSP_CERTSTATUS;
+
+/*   SingleResponse ::= SEQUENCE {
+ *      certID                       CertID,
+ *      certStatus                   CertStatus,
+ *      thisUpdate                   GeneralizedTime,
+ *      nextUpdate           [0]     EXPLICIT GeneralizedTime OPTIONAL,
+ *      singleExtensions     [1]     EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_single_response_st
+	{
+	OCSP_CERTID *certId;
+	OCSP_CERTSTATUS *certStatus;
+	ASN1_GENERALIZEDTIME *thisUpdate;
+	ASN1_GENERALIZEDTIME *nextUpdate;
+	STACK_OF(X509_EXTENSION) *singleExtensions;
+	} OCSP_SINGLERESP;
+
+DECLARE_STACK_OF(OCSP_SINGLERESP)
+DECLARE_ASN1_SET_OF(OCSP_SINGLERESP)
+
+/*   ResponseData ::= SEQUENCE {
+ *      version              [0] EXPLICIT Version DEFAULT v1,
+ *      responderID              ResponderID,
+ *      producedAt               GeneralizedTime,
+ *      responses                SEQUENCE OF SingleResponse,
+ *      responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
+ */
+typedef struct ocsp_response_data_st
+	{
+	ASN1_INTEGER *version;
+	OCSP_RESPID  *responderId;
+	ASN1_GENERALIZEDTIME *producedAt;
+	STACK_OF(OCSP_SINGLERESP) *responses;
+	STACK_OF(X509_EXTENSION) *responseExtensions;
+	} OCSP_RESPDATA;
+
+/*   BasicOCSPResponse       ::= SEQUENCE {
+ *      tbsResponseData      ResponseData,
+ *      signatureAlgorithm   AlgorithmIdentifier,
+ *      signature            BIT STRING,
+ *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
+ */
+  /* Note 1:
+     The value for "signature" is specified in the OCSP rfc2560 as follows:
+     "The value for the signature SHALL be computed on the hash of the DER
+     encoding ResponseData."  This means that you must hash the DER-encoded
+     tbsResponseData, and then run it through a crypto-signing function, which
+     will (at least w/RSA) do a hash-'n'-private-encrypt operation.  This seems
+     a bit odd, but that's the spec.  Also note that the data structures do not
+     leave anywhere to independently specify the algorithm used for the initial
+     hash. So, we look at the signature-specification algorithm, and try to do
+     something intelligent.	-- Kathy Weinhold, CertCo */
+  /* Note 2:
+     It seems that the mentioned passage from RFC 2560 (section 4.2.1) is open
+     for interpretation.  I've done tests against another responder, and found
+     that it doesn't do the double hashing that the RFC seems to say one
+     should.  Therefore, all relevant functions take a flag saying which
+     variant should be used.	-- Richard Levitte, OpenSSL team and CeloCom */
+typedef struct ocsp_basic_response_st
+	{
+	OCSP_RESPDATA *tbsResponseData;
+	X509_ALGOR *signatureAlgorithm;
+	ASN1_BIT_STRING *signature;
+	STACK_OF(X509) *certs;
+	} OCSP_BASICRESP;
+
+/*
+ *   CRLReason ::= ENUMERATED {
+ *        unspecified             (0),
+ *        keyCompromise           (1),
+ *        cACompromise            (2),
+ *        affiliationChanged      (3),
+ *        superseded              (4),
+ *        cessationOfOperation    (5),
+ *        certificateHold         (6),
+ *        removeFromCRL           (8) }
+ */
+#define OCSP_REVOKED_STATUS_NOSTATUS               -1
+#define OCSP_REVOKED_STATUS_UNSPECIFIED             0
+#define OCSP_REVOKED_STATUS_KEYCOMPROMISE           1
+#define OCSP_REVOKED_STATUS_CACOMPROMISE            2
+#define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED      3
+#define OCSP_REVOKED_STATUS_SUPERSEDED              4
+#define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION    5
+#define OCSP_REVOKED_STATUS_CERTIFICATEHOLD         6
+#define OCSP_REVOKED_STATUS_REMOVEFROMCRL           8
+
+/* CrlID ::= SEQUENCE {
+ *     crlUrl               [0]     EXPLICIT IA5String OPTIONAL,
+ *     crlNum               [1]     EXPLICIT INTEGER OPTIONAL,
+ *     crlTime              [2]     EXPLICIT GeneralizedTime OPTIONAL }
+ */
+typedef struct ocsp_crl_id_st
+        {
+	ASN1_IA5STRING *crlUrl;
+	ASN1_INTEGER *crlNum;
+	ASN1_GENERALIZEDTIME *crlTime;
+        } OCSP_CRLID;
+
+/* ServiceLocator ::= SEQUENCE {
+ *      issuer    Name,
+ *      locator   AuthorityInfoAccessSyntax OPTIONAL }
+ */
+typedef struct ocsp_service_locator_st
+        {
+	X509_NAME* issuer;
+	STACK_OF(ACCESS_DESCRIPTION) *locator;
+        } OCSP_SERVICELOC;
+ 
+#define PEM_STRING_OCSP_REQUEST	"OCSP REQUEST"
+#define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE"
+
+#define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p)
+
+#define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p)
+
+#define	PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \
+     (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL)
+
+#define	PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\
+     (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL)
+
+#define PEM_write_bio_OCSP_REQUEST(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\
+			bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+#define PEM_write_bio_OCSP_RESPONSE(bp,o) \
+    PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\
+			bp,(char *)o, NULL,NULL,0,NULL,NULL)
+
+#define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o)
+
+#define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o)
+
+#define OCSP_REQUEST_sign(o,pkey,md) \
+	ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\
+		o->optionalSignature->signatureAlgorithm,NULL,\
+	        o->optionalSignature->signature,o->tbsRequest,pkey,md)
+
+#define OCSP_BASICRESP_sign(o,pkey,md,d) \
+	ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\
+		o->signature,o->tbsResponseData,pkey,md)
+
+#define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\
+        a->optionalSignature->signatureAlgorithm,\
+	a->optionalSignature->signature,a->tbsRequest,r)
+
+#define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\
+	a->signatureAlgorithm,a->signature,a->tbsResponseData,r)
+
+#define ASN1_BIT_STRING_digest(data,type,md,len) \
+	ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len)
+
+#define OCSP_CERTID_dup(cid) ASN1_dup_of(OCSP_CERTID,i2d_OCSP_CERTID,d2i_OCSP_CERTID,cid)
+
+#define OCSP_CERTSTATUS_dup(cs)\
+                (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\
+		(char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs))
+
+OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req);
+
+OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer);
+
+OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, 
+			      X509_NAME *issuerName, 
+			      ASN1_BIT_STRING* issuerKey, 
+			      ASN1_INTEGER *serialNumber);
+
+OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid);
+
+int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len);
+int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len);
+int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs);
+int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req);
+
+int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm);
+int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert);
+
+int OCSP_request_sign(OCSP_REQUEST   *req,
+		      X509           *signer,
+		      EVP_PKEY       *key,
+		      const EVP_MD   *dgst,
+		      STACK_OF(X509) *certs,
+		      unsigned long flags);
+
+int OCSP_response_status(OCSP_RESPONSE *resp);
+OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp);
+
+int OCSP_resp_count(OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx);
+int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last);
+int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason,
+				ASN1_GENERALIZEDTIME **revtime,
+				ASN1_GENERALIZEDTIME **thisupd,
+				ASN1_GENERALIZEDTIME **nextupd);
+int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status,
+				int *reason,
+				ASN1_GENERALIZEDTIME **revtime,
+				ASN1_GENERALIZEDTIME **thisupd,
+				ASN1_GENERALIZEDTIME **nextupd);
+int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd,
+			ASN1_GENERALIZEDTIME *nextupd,
+			long sec, long maxsec);
+
+int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, X509_STORE *store, unsigned long flags);
+
+int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl);
+
+int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
+
+int OCSP_request_onereq_count(OCSP_REQUEST *req);
+OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i);
+OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one);
+int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd,
+			ASN1_OCTET_STRING **pikeyHash,
+			ASN1_INTEGER **pserial, OCSP_CERTID *cid);
+int OCSP_request_is_signed(OCSP_REQUEST *req);
+OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs);
+OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp,
+						OCSP_CERTID *cid,
+						int status, int reason,
+						ASN1_TIME *revtime,
+					ASN1_TIME *thisupd, ASN1_TIME *nextupd);
+int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert);
+int OCSP_basic_sign(OCSP_BASICRESP *brsp, 
+			X509 *signer, EVP_PKEY *key, const EVP_MD *dgst,
+			STACK_OF(X509) *certs, unsigned long flags);
+
+ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
+				void *data, STACK_OF(ASN1_OBJECT) *sk);
+#define ASN1_STRING_encode_of(type,s,i2d,data,sk) \
+((ASN1_STRING *(*)(ASN1_STRING *,I2D_OF(type),type *,STACK_OF(ASN1_OBJECT) *))openssl_fcast(ASN1_STRING_encode))(s,i2d,data,sk)
+
+X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim);
+
+X509_EXTENSION *OCSP_accept_responses_new(char **oids);
+
+X509_EXTENSION *OCSP_archive_cutoff_new(char* tim);
+
+X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME* issuer, char **urls);
+
+int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x);
+int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos);
+int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc);
+X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc);
+void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx);
+int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x);
+int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos);
+int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc);
+X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc);
+void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx);
+int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x);
+int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos);
+int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc);
+X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc);
+void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, int *idx);
+int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc);
+
+int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x);
+int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos);
+int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, int lastpos);
+int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, int lastpos);
+X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc);
+X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc);
+void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, int *idx);
+int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, int crit,
+							unsigned long flags);
+int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc);
+
+DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS)
+DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPID)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE)
+DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES)
+DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ)
+DECLARE_ASN1_FUNCTIONS(OCSP_CERTID)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST)
+DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE)
+DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO)
+DECLARE_ASN1_FUNCTIONS(OCSP_CRLID)
+DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC)
+
+char *OCSP_response_status_str(long s);
+char *OCSP_cert_status_str(long s);
+char *OCSP_crl_reason_str(long s);
+
+int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST* a, unsigned long flags);
+int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE* o, unsigned long flags);
+
+int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
+				X509_STORE *st, unsigned long flags);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_OCSP_strings(void);
+
+/* Error codes for the OCSP functions. */
+
+/* Function codes. */
+#define OCSP_F_ASN1_STRING_ENCODE			 100
+#define OCSP_F_D2I_OCSP_NONCE				 102
+#define OCSP_F_OCSP_BASIC_ADD1_STATUS			 103
+#define OCSP_F_OCSP_BASIC_SIGN				 104
+#define OCSP_F_OCSP_BASIC_VERIFY			 105
+#define OCSP_F_OCSP_CERT_ID_NEW				 101
+#define OCSP_F_OCSP_CHECK_DELEGATED			 106
+#define OCSP_F_OCSP_CHECK_IDS				 107
+#define OCSP_F_OCSP_CHECK_ISSUER			 108
+#define OCSP_F_OCSP_CHECK_VALIDITY			 115
+#define OCSP_F_OCSP_MATCH_ISSUERID			 109
+#define OCSP_F_OCSP_PARSE_URL				 114
+#define OCSP_F_OCSP_REQUEST_SIGN			 110
+#define OCSP_F_OCSP_REQUEST_VERIFY			 116
+#define OCSP_F_OCSP_RESPONSE_GET1_BASIC			 111
+#define OCSP_F_OCSP_SENDREQ_BIO				 112
+#define OCSP_F_REQUEST_VERIFY				 113
+
+/* Reason codes. */
+#define OCSP_R_BAD_DATA					 100
+#define OCSP_R_CERTIFICATE_VERIFY_ERROR			 101
+#define OCSP_R_DIGEST_ERR				 102
+#define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD		 122
+#define OCSP_R_ERROR_IN_THISUPDATE_FIELD		 123
+#define OCSP_R_ERROR_PARSING_URL			 121
+#define OCSP_R_MISSING_OCSPSIGNING_USAGE		 103
+#define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE		 124
+#define OCSP_R_NOT_BASIC_RESPONSE			 104
+#define OCSP_R_NO_CERTIFICATES_IN_CHAIN			 105
+#define OCSP_R_NO_CONTENT				 106
+#define OCSP_R_NO_PUBLIC_KEY				 107
+#define OCSP_R_NO_RESPONSE_DATA				 108
+#define OCSP_R_NO_REVOKED_TIME				 109
+#define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 110
+#define OCSP_R_REQUEST_NOT_SIGNED			 128
+#define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA	 111
+#define OCSP_R_ROOT_CA_NOT_TRUSTED			 112
+#define OCSP_R_SERVER_READ_ERROR			 113
+#define OCSP_R_SERVER_RESPONSE_ERROR			 114
+#define OCSP_R_SERVER_RESPONSE_PARSE_ERROR		 115
+#define OCSP_R_SERVER_WRITE_ERROR			 116
+#define OCSP_R_SIGNATURE_FAILURE			 117
+#define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND		 118
+#define OCSP_R_STATUS_EXPIRED				 125
+#define OCSP_R_STATUS_NOT_YET_VALID			 126
+#define OCSP_R_STATUS_TOO_OLD				 127
+#define OCSP_R_UNKNOWN_MESSAGE_DIGEST			 119
+#define OCSP_R_UNKNOWN_NID				 120
+#define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE		 129
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/opensslconf.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/opensslconf.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/opensslconf.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,202 @@
+/* opensslconf.h */
+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
+
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
+
+#ifndef OPENSSL_NO_GMP
+# define OPENSSL_NO_GMP
+#endif
+#ifndef OPENSSL_NO_KRB5
+# define OPENSSL_NO_KRB5
+#endif
+#ifndef OPENSSL_NO_MDC2
+# define OPENSSL_NO_MDC2
+#endif
+#ifndef OPENSSL_NO_RC5
+# define OPENSSL_NO_RC5
+#endif
+
+#endif /* OPENSSL_DOING_MAKEDEPEND */
+#ifndef OPENSSL_NO_DYNAMIC_ENGINE
+# define OPENSSL_NO_DYNAMIC_ENGINE
+#endif
+
+/* The OPENSSL_NO_* macros are also defined as NO_* if the application
+   asks for it.  This is a transient feature that is provided for those
+   who haven't had the time to do the appropriate changes in their
+   applications.  */
+#ifdef OPENSSL_ALGORITHM_DEFINES
+# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP)
+#  define NO_GMP
+# endif
+# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5)
+#  define NO_KRB5
+# endif
+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2)
+#  define NO_MDC2
+# endif
+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5)
+#  define NO_RC5
+# endif
+#endif
+
+/* crypto/opensslconf.h.in */
+
+/* Generate 80386 code? */
+#undef I386_ONLY
+
+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
+#define ENGINESDIR "/usr/local/ssl/lib/engines"
+#define OPENSSLDIR "/usr/local/ssl"
+#endif
+#endif
+
+#undef OPENSSL_UNISTD
+#define OPENSSL_UNISTD <unistd.h>
+
+#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
+
+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
+#define IDEA_INT unsigned int
+#endif
+
+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
+#define MD2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
+/* I need to put in a mod for the alpha - eay */
+#define RC2_INT unsigned int
+#endif
+
+#if defined(HEADER_RC4_H)
+#if !defined(RC4_INT)
+/* using int types make the structure larger but make the code faster
+ * on most boxes I have tested - up to %20 faster. */
+/*
+ * I don't know what does "most" mean, but declaring "int" is a must on:
+ * - Intel P6 because partial register stalls are very expensive;
+ * - elder Alpha because it lacks byte load/store instructions;
+ */
+#define RC4_INT unsigned int
+#endif
+#if !defined(RC4_CHUNK)
+/*
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+#undef RC4_CHUNK
+#endif
+#endif
+
+#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+#ifndef DES_LONG
+#define DES_LONG unsigned long
+#endif
+#endif
+
+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+#define CONFIG_HEADER_BN_H
+#undef BN_LLONG
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+/* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+#undef SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#define THIRTY_TWO_BIT
+#undef SIXTEEN_BIT
+#undef EIGHT_BIT
+#endif
+
+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+#define CONFIG_HEADER_RC4_LOCL_H
+/* if this is defined data[i] is used instead of *data, this is a %20
+ * speedup on x86 */
+#undef RC4_INDEX
+#endif
+
+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+#define CONFIG_HEADER_BF_LOCL_H
+#undef BF_PTR
+#endif /* HEADER_BF_LOCL_H */
+
+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+#define CONFIG_HEADER_DES_LOCL_H
+#ifndef DES_DEFAULT_OPTIONS
+/* the following is tweaked from a config script, that is why it is a
+ * protected undef/define */
+#ifndef DES_PTR
+#undef DES_PTR
+#endif
+
+/* This helps C compiler generate the correct code for multiple functional
+ * units.  It reduces register dependancies at the expense of 2 more
+ * registers */
+#ifndef DES_RISC1
+#undef DES_RISC1
+#endif
+
+#ifndef DES_RISC2
+#undef DES_RISC2
+#endif
+
+#if defined(DES_RISC1) && defined(DES_RISC2)
+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
+#endif
+
+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+#ifndef DES_UNROLL
+#undef DES_UNROLL
+#endif
+
+/* These default values were supplied by
+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
+ * They are only used if nothing else has been defined */
+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
+/* Special defines which change the way the code is built depending on the
+   CPU and OS.  For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
+   even newer MIPS CPU's, but at the moment one size fits all for
+   optimization options.  Older Sparc's work better with only UNROLL, but
+   there's no way to tell at compile time what it is you're running on */
+ 
+#if defined( sun )		/* Newer Sparc's */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#elif defined( __ultrix )	/* Older MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined( __osf1__ )	/* Alpha */
+#  define DES_PTR
+#  define DES_RISC2
+#elif defined ( _AIX )		/* RS6000 */
+  /* Unknown */
+#elif defined( __hpux )		/* HP-PA */
+  /* Unknown */
+#elif defined( __aux )		/* 68K */
+  /* Unknown */
+#elif defined( __dgux )		/* 88K (but P6 in latest boxes) */
+#  define DES_UNROLL
+#elif defined( __sgi )		/* Newer MIPS */
+#  define DES_PTR
+#  define DES_RISC2
+#  define DES_UNROLL
+#elif defined(i386) || defined(__i386__)	/* x86 boxes, should be gcc */
+#  define DES_PTR
+#  define DES_RISC1
+#  define DES_UNROLL
+#endif /* Systems-specific speed defines */
+#endif
+
+#endif /* DES_DEFAULT_OPTIONS */
+#endif /* HEADER_DES_LOCL_H */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/opensslv.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/opensslv.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/opensslv.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,89 @@
+#ifndef HEADER_OPENSSLV_H
+#define HEADER_OPENSSLV_H
+
+/* Numeric release version identifier:
+ * MNNFFPPS: major minor fix patch status
+ * The status nibble has one of the values 0 for development, 1 to e for betas
+ * 1 to 14, and f for release.  The patch level is exactly that.
+ * For example:
+ * 0.9.3-dev	  0x00903000
+ * 0.9.3-beta1	  0x00903001
+ * 0.9.3-beta2-dev 0x00903002
+ * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
+ * 0.9.3	  0x0090300f
+ * 0.9.3a	  0x0090301f
+ * 0.9.4	  0x0090400f
+ * 1.2.3z	  0x102031af
+ *
+ * For continuity reasons (because 0.9.5 is already out, and is coded
+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
+ * part is slightly different, by setting the highest bit.  This means
+ * that 0.9.5a looks like this: 0x0090581f.  At 0.9.6, we can start
+ * with 0x0090600S...
+ *
+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
+ *  major minor fix final patch/beta)
+ */
+#define OPENSSL_VERSION_NUMBER	0x0090800fL
+#ifdef OPENSSL_FIPS
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8-fips 05 Jul 2005"
+#else
+#define OPENSSL_VERSION_TEXT	"OpenSSL 0.9.8 05 Jul 2005"
+#endif
+#define OPENSSL_VERSION_PTEXT	" part of " OPENSSL_VERSION_TEXT
+
+
+/* The macros below are to be used for shared library (.so, .dll, ...)
+ * versioning.  That kind of versioning works a bit differently between
+ * operating systems.  The most usual scheme is to set a major and a minor
+ * number, and have the runtime loader check that the major number is equal
+ * to what it was at application link time, while the minor number has to
+ * be greater or equal to what it was at application link time.  With this
+ * scheme, the version number is usually part of the file name, like this:
+ *
+ *	libcrypto.so.0.9
+ *
+ * Some unixen also make a softlink with the major verson number only:
+ *
+ *	libcrypto.so.0
+ *
+ * On Tru64 and IRIX 6.x it works a little bit differently.  There, the
+ * shared library version is stored in the file, and is actually a series
+ * of versions, separated by colons.  The rightmost version present in the
+ * library when linking an application is stored in the application to be
+ * matched at run time.  When the application is run, a check is done to
+ * see if the library version stored in the application matches any of the
+ * versions in the version string of the library itself.
+ * This version string can be constructed in any way, depending on what
+ * kind of matching is desired.  However, to implement the same scheme as
+ * the one used in the other unixen, all compatible versions, from lowest
+ * to highest, should be part of the string.  Consecutive builds would
+ * give the following versions strings:
+ *
+ *	3.0
+ *	3.0:3.1
+ *	3.0:3.1:3.2
+ *	4.0
+ *	4.0:4.1
+ *
+ * Notice how version 4 is completely incompatible with version, and
+ * therefore give the breach you can see.
+ *
+ * There may be other schemes as well that I haven't yet discovered.
+ *
+ * So, here's the way it works here: first of all, the library version
+ * number doesn't need at all to match the overall OpenSSL version.
+ * However, it's nice and more understandable if it actually does.
+ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
+ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
+ * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways,
+ * we need to keep a history of version numbers, which is done in the
+ * macro SHLIB_VERSION_HISTORY.  The numbers are separated by colons and
+ * should only keep the versions that are binary compatible with the current.
+ */
+#define SHLIB_VERSION_HISTORY ""
+#define SHLIB_VERSION_NUMBER "0.9.8"
+
+
+#endif /* HEADER_OPENSSLV_H */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ossl_typ.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ossl_typ.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ossl_typ.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,174 @@
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_OPENSSL_TYPES_H
+#define HEADER_OPENSSL_TYPES_H
+
+#include <openssl/e_os2.h>
+
+#ifdef NO_ASN1_TYPEDEFS
+#define ASN1_INTEGER		ASN1_STRING
+#define ASN1_ENUMERATED		ASN1_STRING
+#define ASN1_BIT_STRING		ASN1_STRING
+#define ASN1_OCTET_STRING	ASN1_STRING
+#define ASN1_PRINTABLESTRING	ASN1_STRING
+#define ASN1_T61STRING		ASN1_STRING
+#define ASN1_IA5STRING		ASN1_STRING
+#define ASN1_UTCTIME		ASN1_STRING
+#define ASN1_GENERALIZEDTIME	ASN1_STRING
+#define ASN1_TIME		ASN1_STRING
+#define ASN1_GENERALSTRING	ASN1_STRING
+#define ASN1_UNIVERSALSTRING	ASN1_STRING
+#define ASN1_BMPSTRING		ASN1_STRING
+#define ASN1_VISIBLESTRING	ASN1_STRING
+#define ASN1_UTF8STRING		ASN1_STRING
+#define ASN1_BOOLEAN		int
+#define ASN1_NULL		int
+#else
+typedef struct asn1_string_st ASN1_INTEGER;
+typedef struct asn1_string_st ASN1_ENUMERATED;
+typedef struct asn1_string_st ASN1_BIT_STRING;
+typedef struct asn1_string_st ASN1_OCTET_STRING;
+typedef struct asn1_string_st ASN1_PRINTABLESTRING;
+typedef struct asn1_string_st ASN1_T61STRING;
+typedef struct asn1_string_st ASN1_IA5STRING;
+typedef struct asn1_string_st ASN1_GENERALSTRING;
+typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
+typedef struct asn1_string_st ASN1_BMPSTRING;
+typedef struct asn1_string_st ASN1_UTCTIME;
+typedef struct asn1_string_st ASN1_TIME;
+typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
+typedef struct asn1_string_st ASN1_VISIBLESTRING;
+typedef struct asn1_string_st ASN1_UTF8STRING;
+typedef int ASN1_BOOLEAN;
+typedef int ASN1_NULL;
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+#undef X509_NAME
+#undef X509_CERT_PAIR
+#undef PKCS7_ISSUER_AND_SERIAL
+#endif
+
+#ifdef BIGNUM
+#undef BIGNUM
+#endif
+typedef struct bignum_st BIGNUM;
+typedef struct bignum_ctx BN_CTX;
+typedef struct bn_blinding_st BN_BLINDING;
+typedef struct bn_mont_ctx_st BN_MONT_CTX;
+typedef struct bn_recp_ctx_st BN_RECP_CTX;
+typedef struct bn_gencb_st BN_GENCB;
+
+typedef struct buf_mem_st BUF_MEM;
+
+typedef struct evp_cipher_st EVP_CIPHER;
+typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
+typedef struct env_md_st EVP_MD;
+typedef struct env_md_ctx_st EVP_MD_CTX;
+typedef struct evp_pkey_st EVP_PKEY;
+
+typedef struct dh_st DH;
+typedef struct dh_method DH_METHOD;
+
+typedef struct dsa_st DSA;
+typedef struct dsa_method DSA_METHOD;
+
+typedef struct rsa_st RSA;
+typedef struct rsa_meth_st RSA_METHOD;
+
+typedef struct rand_meth_st RAND_METHOD;
+
+typedef struct ecdh_method ECDH_METHOD;
+typedef struct ecdsa_method ECDSA_METHOD;
+
+typedef struct x509_st X509;
+typedef struct X509_algor_st X509_ALGOR;
+typedef struct X509_crl_st X509_CRL;
+typedef struct X509_name_st X509_NAME;
+typedef struct x509_store_st X509_STORE;
+typedef struct x509_store_ctx_st X509_STORE_CTX;
+
+typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct conf_st CONF;
+
+typedef struct store_st STORE;
+typedef struct store_method_st STORE_METHOD;
+
+typedef struct ui_st UI;
+typedef struct ui_method_st UI_METHOD;
+
+typedef struct st_ERR_FNS ERR_FNS;
+
+typedef struct engine_st ENGINE;
+
+typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
+typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
+typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
+typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
+
+  /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */
+#define DECLARE_PKCS12_STACK_OF(type) /* Nothing */
+#define IMPLEMENT_PKCS12_STACK_OF(type) /* Nothing */
+
+typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
+/* Callback types for crypto.h */
+typedef int CRYPTO_EX_new(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+					int idx, long argl, void *argp);
+typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, void *from_d, 
+					int idx, long argl, void *argp);
+
+#endif /* def HEADER_OPENSSL_TYPES_H */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pem.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pem.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pem.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,737 @@
+/* crypto/pem/pem.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_PEM_H
+#define HEADER_PEM_H
+
+#include <openssl/e_os2.h>
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#ifndef OPENSSL_NO_STACK
+#include <openssl/stack.h>
+#endif
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <openssl/pem2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define PEM_BUFSIZE		1024
+
+#define PEM_OBJ_UNDEF		0
+#define PEM_OBJ_X509		1
+#define PEM_OBJ_X509_REQ	2
+#define PEM_OBJ_CRL		3
+#define PEM_OBJ_SSL_SESSION	4
+#define PEM_OBJ_PRIV_KEY	10
+#define PEM_OBJ_PRIV_RSA	11
+#define PEM_OBJ_PRIV_DSA	12
+#define PEM_OBJ_PRIV_DH		13
+#define PEM_OBJ_PUB_RSA		14
+#define PEM_OBJ_PUB_DSA		15
+#define PEM_OBJ_PUB_DH		16
+#define PEM_OBJ_DHPARAMS	17
+#define PEM_OBJ_DSAPARAMS	18
+#define PEM_OBJ_PRIV_RSA_PUBLIC	19
+#define PEM_OBJ_PRIV_ECDSA	20
+#define PEM_OBJ_PUB_ECDSA	21
+#define PEM_OBJ_ECPARAMETERS	22
+
+#define PEM_ERROR		30
+#define PEM_DEK_DES_CBC         40
+#define PEM_DEK_IDEA_CBC        45
+#define PEM_DEK_DES_EDE         50
+#define PEM_DEK_DES_ECB         60
+#define PEM_DEK_RSA             70
+#define PEM_DEK_RSA_MD2         80
+#define PEM_DEK_RSA_MD5         90
+
+#define PEM_MD_MD2		NID_md2
+#define PEM_MD_MD5		NID_md5
+#define PEM_MD_SHA		NID_sha
+#define PEM_MD_MD2_RSA		NID_md2WithRSAEncryption
+#define PEM_MD_MD5_RSA		NID_md5WithRSAEncryption
+#define PEM_MD_SHA_RSA		NID_sha1WithRSAEncryption
+
+#define PEM_STRING_X509_OLD	"X509 CERTIFICATE"
+#define PEM_STRING_X509		"CERTIFICATE"
+#define PEM_STRING_X509_PAIR	"CERTIFICATE PAIR"
+#define PEM_STRING_X509_TRUSTED	"TRUSTED CERTIFICATE"
+#define PEM_STRING_X509_REQ_OLD	"NEW CERTIFICATE REQUEST"
+#define PEM_STRING_X509_REQ	"CERTIFICATE REQUEST"
+#define PEM_STRING_X509_CRL	"X509 CRL"
+#define PEM_STRING_EVP_PKEY	"ANY PRIVATE KEY"
+#define PEM_STRING_PUBLIC	"PUBLIC KEY"
+#define PEM_STRING_RSA		"RSA PRIVATE KEY"
+#define PEM_STRING_RSA_PUBLIC	"RSA PUBLIC KEY"
+#define PEM_STRING_DSA		"DSA PRIVATE KEY"
+#define PEM_STRING_DSA_PUBLIC	"DSA PUBLIC KEY"
+#define PEM_STRING_PKCS7	"PKCS7"
+#define PEM_STRING_PKCS8	"ENCRYPTED PRIVATE KEY"
+#define PEM_STRING_PKCS8INF	"PRIVATE KEY"
+#define PEM_STRING_DHPARAMS	"DH PARAMETERS"
+#define PEM_STRING_SSL_SESSION	"SSL SESSION PARAMETERS"
+#define PEM_STRING_DSAPARAMS	"DSA PARAMETERS"
+#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
+#define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
+#define PEM_STRING_ECPRIVATEKEY	"EC PRIVATE KEY"
+
+  /* Note that this structure is initialised by PEM_SealInit and cleaned up
+     by PEM_SealFinal (at least for now) */
+typedef struct PEM_Encode_Seal_st
+	{
+	EVP_ENCODE_CTX encode;
+	EVP_MD_CTX md;
+	EVP_CIPHER_CTX cipher;
+	} PEM_ENCODE_SEAL_CTX;
+
+/* enc_type is one off */
+#define PEM_TYPE_ENCRYPTED      10
+#define PEM_TYPE_MIC_ONLY       20
+#define PEM_TYPE_MIC_CLEAR      30
+#define PEM_TYPE_CLEAR		40
+
+typedef struct pem_recip_st
+	{
+	char *name;
+	X509_NAME *dn;
+
+	int cipher;
+	int key_enc;
+	/*	char iv[8]; unused and wrong size */
+	} PEM_USER;
+
+typedef struct pem_ctx_st
+	{
+	int type;		/* what type of object */
+
+	struct	{
+		int version;	
+		int mode;		
+		} proc_type;
+
+	char *domain;
+
+	struct	{
+		int cipher;
+	/* unused, and wrong size
+	   unsigned char iv[8]; */
+		} DEK_info;
+		
+	PEM_USER *originator;
+
+	int num_recipient;
+	PEM_USER **recipient;
+
+#ifndef OPENSSL_NO_STACK
+	STACK *x509_chain;	/* certificate chain */
+#else
+	char *x509_chain;	/* certificate chain */
+#endif
+	EVP_MD *md;		/* signature type */
+
+	int md_enc;		/* is the md encrypted or not? */
+	int md_len;		/* length of md_data */
+	char *md_data;		/* message digest, could be pkey encrypted */
+
+	EVP_CIPHER *dec;	/* date encryption cipher */
+	int key_len;		/* key length */
+	unsigned char *key;	/* key */
+	/* unused, and wrong size
+	   unsigned char iv[8]; */
+
+	
+	int  data_enc;		/* is the data encrypted */
+	int data_len;
+	unsigned char *data;
+	} PEM_CTX;
+
+/* These macros make the PEM_read/PEM_write functions easier to maintain and
+ * write. Now they are all implemented with either:
+ * IMPLEMENT_PEM_rw(...) or IMPLEMENT_PEM_rw_cb(...)
+ */
+
+#ifdef OPENSSL_NO_FP_API
+
+#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/
+#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/
+
+#else
+
+#define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
+type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return(((type *(*)(D2I_OF(type),char *,FILE *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read))(d2i_##asn1, str,fp,x,cb,u)); \
+} \
+
+#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x) \
+{ \
+return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \
+}
+
+#define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, const type *x) \
+{ \
+return(((int (*)(I2D_OF_const(type),const char *,FILE *, const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL)); \
+}
+
+#define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, \
+		  void *u) \
+	{ \
+	return(((int (*)(I2D_OF(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \
+	}
+
+#define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
+int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, \
+		  void *u) \
+	{ \
+	return(((int (*)(I2D_OF_const(type),const char *,FILE *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write))(i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u)); \
+	}
+
+#endif
+
+#define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
+{ \
+return(((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i_##asn1, str,bp,x,cb,u)); \
+}
+
+#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x) \
+{ \
+return(((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \
+}
+
+#define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, const type *x) \
+{ \
+return(((int (*)(I2D_OF_const(type),const char *,BIO *,const type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL)); \
+}
+
+#define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+	{ \
+	return(((int (*)(I2D_OF(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \
+	}
+
+#define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
+	{ \
+	return(((int (*)(I2D_OF_const(type),const char *,BIO *,type *,const EVP_CIPHER *,unsigned char *,int,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u)); \
+	}
+
+#define IMPLEMENT_PEM_write(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_fp(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_write_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
+	IMPLEMENT_PEM_read_fp(name, type, str, asn1) 
+
+#define IMPLEMENT_PEM_rw(name, type, str, asn1) \
+	IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_write(name, type, str, asn1)
+
+#define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \
+	IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_const(name, type, str, asn1)
+
+#define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \
+	IMPLEMENT_PEM_read(name, type, str, asn1) \
+	IMPLEMENT_PEM_write_cb(name, type, str, asn1)
+
+/* These are the same except they are for the declarations */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_NO_FP_API)
+
+#define DECLARE_PEM_read_fp(name, type) /**/
+#define DECLARE_PEM_write_fp(name, type) /**/
+#define DECLARE_PEM_write_cb_fp(name, type) /**/
+
+#else
+
+#define DECLARE_PEM_read_fp(name, type) \
+	type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
+
+#define DECLARE_PEM_write_fp(name, type) \
+	int PEM_write_##name(FILE *fp, type *x);
+
+#define DECLARE_PEM_write_fp_const(name, type) \
+	int PEM_write_##name(FILE *fp, const type *x);
+
+#define DECLARE_PEM_write_cb_fp(name, type) \
+	int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+#endif
+
+#ifndef OPENSSL_NO_BIO
+#define DECLARE_PEM_read_bio(name, type) \
+	type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
+
+#define DECLARE_PEM_write_bio(name, type) \
+	int PEM_write_bio_##name(BIO *bp, type *x);
+
+#define DECLARE_PEM_write_bio_const(name, type) \
+	int PEM_write_bio_##name(BIO *bp, const type *x);
+
+#define DECLARE_PEM_write_cb_bio(name, type) \
+	int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
+	     unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
+
+#else
+
+#define DECLARE_PEM_read_bio(name, type) /**/
+#define DECLARE_PEM_write_bio(name, type) /**/
+#define DECLARE_PEM_write_cb_bio(name, type) /**/
+
+#endif
+
+#define DECLARE_PEM_write(name, type) \
+	DECLARE_PEM_write_bio(name, type) \
+	DECLARE_PEM_write_fp(name, type) 
+
+#define DECLARE_PEM_write_const(name, type) \
+	DECLARE_PEM_write_bio_const(name, type) \
+	DECLARE_PEM_write_fp_const(name, type)
+
+#define DECLARE_PEM_write_cb(name, type) \
+	DECLARE_PEM_write_cb_bio(name, type) \
+	DECLARE_PEM_write_cb_fp(name, type) 
+
+#define DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_read_bio(name, type) \
+	DECLARE_PEM_read_fp(name, type)
+
+#define DECLARE_PEM_rw(name, type) \
+	DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_write(name, type)
+
+#define DECLARE_PEM_rw_const(name, type) \
+	DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_write_const(name, type)
+
+#define DECLARE_PEM_rw_cb(name, type) \
+	DECLARE_PEM_read(name, type) \
+	DECLARE_PEM_write_cb(name, type)
+
+#ifdef SSLEAY_MACROS
+
+#define PEM_write_SSL_SESSION(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
+			PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_X509(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_X509,PEM_STRING_X509,fp, \
+			(char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_X509_REQ(fp,x) PEM_ASN1_write( \
+		(int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,fp,(char *)x, \
+			NULL,NULL,0,NULL,NULL)
+#define PEM_write_X509_CRL(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL, \
+			fp,(char *)x, NULL,NULL,0,NULL,NULL)
+#define	PEM_write_RSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,fp,\
+			(char *)x,enc,kstr,klen,cb,u)
+#define	PEM_write_RSAPublicKey(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_RSAPublicKey,\
+			PEM_STRING_RSA_PUBLIC,fp,(char *)x,NULL,NULL,0,NULL,NULL)
+#define	PEM_write_DSAPrivateKey(fp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,fp,\
+			(char *)x,enc,kstr,klen,cb,u)
+#define	PEM_write_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write((int (*)())i2d_PrivateKey,\
+		(((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
+			bp,(char *)x,enc,kstr,klen,cb,u)
+#define PEM_write_PKCS7(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,fp, \
+			(char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_DHparams(fp,x) \
+		PEM_ASN1_write((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,fp,\
+			(char *)x,NULL,NULL,0,NULL,NULL)
+
+#define PEM_write_NETSCAPE_CERT_SEQUENCE(fp,x) \
+                PEM_ASN1_write((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
+			PEM_STRING_X509,fp, \
+                        (char *)x, NULL,NULL,0,NULL,NULL)
+
+#define	PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
+	(char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
+#define	PEM_read_X509(fp,x,cb,u) (X509 *)PEM_ASN1_read( \
+	(char *(*)())d2i_X509,PEM_STRING_X509,fp,(char **)x,cb,u)
+#define	PEM_read_X509_REQ(fp,x,cb,u) (X509_REQ *)PEM_ASN1_read( \
+	(char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,fp,(char **)x,cb,u)
+#define	PEM_read_X509_CRL(fp,x,cb,u) (X509_CRL *)PEM_ASN1_read( \
+	(char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,fp,(char **)x,cb,u)
+#define	PEM_read_RSAPrivateKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
+	(char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,fp,(char **)x,cb,u)
+#define	PEM_read_RSAPublicKey(fp,x,cb,u) (RSA *)PEM_ASN1_read( \
+	(char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,fp,(char **)x,cb,u)
+#define	PEM_read_DSAPrivateKey(fp,x,cb,u) (DSA *)PEM_ASN1_read( \
+	(char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,fp,(char **)x,cb,u)
+#define	PEM_read_PrivateKey(fp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read( \
+	(char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,fp,(char **)x,cb,u)
+#define	PEM_read_PKCS7(fp,x,cb,u) (PKCS7 *)PEM_ASN1_read( \
+	(char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,fp,(char **)x,cb,u)
+#define	PEM_read_DHparams(fp,x,cb,u) (DH *)PEM_ASN1_read( \
+	(char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,fp,(char **)x,cb,u)
+
+#define PEM_read_NETSCAPE_CERT_SEQUENCE(fp,x,cb,u) \
+		(NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read( \
+        (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,fp,\
+							(char **)x,cb,u)
+
+#define PEM_write_bio_X509(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_X509,PEM_STRING_X509,bp, \
+			(char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_X509_REQ(bp,x) PEM_ASN1_write_bio( \
+		(int (*)())i2d_X509_REQ,PEM_STRING_X509_REQ,bp,(char *)x, \
+			NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_X509_CRL(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_X509_CRL,PEM_STRING_X509_CRL,\
+			bp,(char *)x, NULL,NULL,0,NULL,NULL)
+#define	PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write_bio((int (*)())i2d_RSAPrivateKey,PEM_STRING_RSA,\
+			bp,(char *)x,enc,kstr,klen,cb,u)
+#define	PEM_write_bio_RSAPublicKey(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_RSAPublicKey, \
+			PEM_STRING_RSA_PUBLIC,\
+			bp,(char *)x,NULL,NULL,0,NULL,NULL)
+#define	PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write_bio((int (*)())i2d_DSAPrivateKey,PEM_STRING_DSA,\
+			bp,(char *)x,enc,kstr,klen,cb,u)
+#define	PEM_write_bio_PrivateKey(bp,x,enc,kstr,klen,cb,u) \
+		PEM_ASN1_write_bio((int (*)())i2d_PrivateKey,\
+		(((x)->type == EVP_PKEY_DSA)?PEM_STRING_DSA:PEM_STRING_RSA),\
+			bp,(char *)x,enc,kstr,klen,cb,u)
+#define PEM_write_bio_PKCS7(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_PKCS7,PEM_STRING_PKCS7,bp, \
+			(char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_DHparams(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_DHparams,PEM_STRING_DHPARAMS,\
+			bp,(char *)x,NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_DSAparams(bp,x) \
+		PEM_ASN1_write_bio((int (*)())i2d_DSAparams, \
+			PEM_STRING_DSAPARAMS,bp,(char *)x,NULL,NULL,0,NULL,NULL)
+
+#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE(bp,x) \
+                PEM_ASN1_write_bio((int (*)())i2d_NETSCAPE_CERT_SEQUENCE, \
+			PEM_STRING_X509,bp, \
+                        (char *)x, NULL,NULL,0,NULL,NULL)
+
+#define	PEM_read_bio_X509(bp,x,cb,u) (X509 *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_X509,PEM_STRING_X509,bp,(char **)x,cb,u)
+#define	PEM_read_bio_X509_REQ(bp,x,cb,u) (X509_REQ *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_X509_REQ,PEM_STRING_X509_REQ,bp,(char **)x,cb,u)
+#define	PEM_read_bio_X509_CRL(bp,x,cb,u) (X509_CRL *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_X509_CRL,PEM_STRING_X509_CRL,bp,(char **)x,cb,u)
+#define	PEM_read_bio_RSAPrivateKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_RSAPrivateKey,PEM_STRING_RSA,bp,(char **)x,cb,u)
+#define	PEM_read_bio_RSAPublicKey(bp,x,cb,u) (RSA *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_RSAPublicKey,PEM_STRING_RSA_PUBLIC,bp,(char **)x,cb,u)
+#define	PEM_read_bio_DSAPrivateKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_DSAPrivateKey,PEM_STRING_DSA,bp,(char **)x,cb,u)
+#define	PEM_read_bio_PrivateKey(bp,x,cb,u) (EVP_PKEY *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_PrivateKey,PEM_STRING_EVP_PKEY,bp,(char **)x,cb,u)
+
+#define	PEM_read_bio_PKCS7(bp,x,cb,u) (PKCS7 *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_PKCS7,PEM_STRING_PKCS7,bp,(char **)x,cb,u)
+#define	PEM_read_bio_DHparams(bp,x,cb,u) (DH *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_DHparams,PEM_STRING_DHPARAMS,bp,(char **)x,cb,u)
+#define	PEM_read_bio_DSAparams(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \
+	(char *(*)())d2i_DSAparams,PEM_STRING_DSAPARAMS,bp,(char **)x,cb,u)
+
+#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE(bp,x,cb,u) \
+		(NETSCAPE_CERT_SEQUENCE *)PEM_ASN1_read_bio( \
+        (char *(*)())d2i_NETSCAPE_CERT_SEQUENCE,PEM_STRING_X509,bp,\
+							(char **)x,cb,u)
+
+#endif
+
+#if 1
+/* "userdata": new with OpenSSL 0.9.4 */
+typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata);
+#else
+/* OpenSSL 0.9.3, 0.9.3a */
+typedef int pem_password_cb(char *buf, int size, int rwflag);
+#endif
+
+int	PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
+int	PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len,
+	pem_password_cb *callback,void *u);
+
+#ifndef OPENSSL_NO_BIO
+int	PEM_read_bio(BIO *bp, char **name, char **header,
+		unsigned char **data,long *len);
+int	PEM_write_bio(BIO *bp,const char *name,char *hdr,unsigned char *data,
+		long len);
+int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp,
+	     pem_password_cb *cb, void *u);
+void *	PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp,
+			  void **x, pem_password_cb *cb, void *u);
+#define PEM_ASN1_read_bio_of(type,d2i,name,bp,x,cb,u) \
+((type *(*)(D2I_OF(type),const char *,BIO *,type **,pem_password_cb *,void *))openssl_fcast(PEM_ASN1_read_bio))(d2i,name,bp,x,cb,u)
+int	PEM_ASN1_write_bio(i2d_of_void *i2d,const char *name,BIO *bp,char *x,
+			   const EVP_CIPHER *enc,unsigned char *kstr,int klen,
+			   pem_password_cb *cb, void *u);
+#define PEM_ASN1_write_bio_of(type,i2d,name,bp,x,enc,kstr,klen,cb,u) \
+	((int (*)(I2D_OF(type),const char *,BIO *,type *, const EVP_CIPHER *,unsigned char *,int, pem_password_cb *,void *))openssl_fcast(PEM_ASN1_write_bio))(i2d,name,bp,x,enc,kstr,klen,cb,u)
+
+STACK_OF(X509_INFO) *	PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u);
+int	PEM_X509_INFO_write_bio(BIO *bp,X509_INFO *xi, EVP_CIPHER *enc,
+		unsigned char *kstr, int klen, pem_password_cb *cd, void *u);
+#endif
+
+#ifndef OPENSSL_SYS_WIN16
+int	PEM_read(FILE *fp, char **name, char **header,
+		unsigned char **data,long *len);
+int	PEM_write(FILE *fp,char *name,char *hdr,unsigned char *data,long len);
+void *  PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
+		      pem_password_cb *cb, void *u);
+int	PEM_ASN1_write(i2d_of_void *i2d,const char *name,FILE *fp,
+		       char *x,const EVP_CIPHER *enc,unsigned char *kstr,
+		       int klen,pem_password_cb *callback, void *u);
+STACK_OF(X509_INFO) *	PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
+	pem_password_cb *cb, void *u);
+#endif
+
+int	PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
+		EVP_MD *md_type, unsigned char **ek, int *ekl,
+		unsigned char *iv, EVP_PKEY **pubk, int npubk);
+void	PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
+		unsigned char *in, int inl);
+int	PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig,int *sigl,
+		unsigned char *out, int *outl, EVP_PKEY *priv);
+
+void    PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
+void    PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt);
+int	PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+		unsigned int *siglen, EVP_PKEY *pkey);
+
+int	PEM_def_callback(char *buf, int num, int w, void *key);
+void	PEM_proc_type(char *buf, int type);
+void	PEM_dek_info(char *buf, const char *type, int len, char *str);
+
+#ifndef SSLEAY_MACROS
+
+#include <openssl/symhacks.h>
+
+DECLARE_PEM_rw(X509, X509)
+
+DECLARE_PEM_rw(X509_AUX, X509)
+
+DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR)
+
+DECLARE_PEM_rw(X509_REQ, X509_REQ)
+DECLARE_PEM_write(X509_REQ_NEW, X509_REQ)
+
+DECLARE_PEM_rw(X509_CRL, X509_CRL)
+
+DECLARE_PEM_rw(PKCS7, PKCS7)
+
+DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
+
+DECLARE_PEM_rw(PKCS8, X509_SIG)
+
+DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
+
+#ifndef OPENSSL_NO_RSA
+
+DECLARE_PEM_rw_cb(RSAPrivateKey, RSA)
+
+DECLARE_PEM_rw_const(RSAPublicKey, RSA)
+DECLARE_PEM_rw(RSA_PUBKEY, RSA)
+
+#endif
+
+#ifndef OPENSSL_NO_DSA
+
+DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
+
+DECLARE_PEM_rw(DSA_PUBKEY, DSA)
+
+DECLARE_PEM_rw_const(DSAparams, DSA)
+
+#endif
+
+#ifndef OPENSSL_NO_EC
+DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
+DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
+DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
+#endif
+
+#ifndef OPENSSL_NO_DH
+
+DECLARE_PEM_rw_const(DHparams, DH)
+
+#endif
+
+DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
+
+DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
+
+int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
+                                  char *, int, pem_password_cb *, void *);
+int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+
+int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
+				  char *kstr, int klen,
+				  pem_password_cb *cb, void *u);
+
+EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u);
+
+int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc,
+			      char *kstr,int klen, pem_password_cb *cd, void *u);
+
+#endif /* SSLEAY_MACROS */
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_PEM_strings(void);
+
+/* Error codes for the PEM functions. */
+
+/* Function codes. */
+#define PEM_F_D2I_PKCS8PRIVATEKEY_BIO			 120
+#define PEM_F_D2I_PKCS8PRIVATEKEY_FP			 121
+#define PEM_F_DO_PK8PKEY				 126
+#define PEM_F_DO_PK8PKEY_FP				 125
+#define PEM_F_LOAD_IV					 101
+#define PEM_F_PEM_ASN1_READ				 102
+#define PEM_F_PEM_ASN1_READ_BIO				 103
+#define PEM_F_PEM_ASN1_WRITE				 104
+#define PEM_F_PEM_ASN1_WRITE_BIO			 105
+#define PEM_F_PEM_DEF_CALLBACK				 100
+#define PEM_F_PEM_DO_HEADER				 106
+#define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY		 118
+#define PEM_F_PEM_GET_EVP_CIPHER_INFO			 107
+#define PEM_F_PEM_PK8PKEY				 119
+#define PEM_F_PEM_READ					 108
+#define PEM_F_PEM_READ_BIO				 109
+#define PEM_F_PEM_READ_BIO_PRIVATEKEY			 123
+#define PEM_F_PEM_READ_PRIVATEKEY			 124
+#define PEM_F_PEM_SEALFINAL				 110
+#define PEM_F_PEM_SEALINIT				 111
+#define PEM_F_PEM_SIGNFINAL				 112
+#define PEM_F_PEM_WRITE					 113
+#define PEM_F_PEM_WRITE_BIO				 114
+#define PEM_F_PEM_X509_INFO_READ			 115
+#define PEM_F_PEM_X509_INFO_READ_BIO			 116
+#define PEM_F_PEM_X509_INFO_WRITE_BIO			 117
+
+/* Reason codes. */
+#define PEM_R_BAD_BASE64_DECODE				 100
+#define PEM_R_BAD_DECRYPT				 101
+#define PEM_R_BAD_END_LINE				 102
+#define PEM_R_BAD_IV_CHARS				 103
+#define PEM_R_BAD_PASSWORD_READ				 104
+#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY		 115
+#define PEM_R_NOT_DEK_INFO				 105
+#define PEM_R_NOT_ENCRYPTED				 106
+#define PEM_R_NOT_PROC_TYPE				 107
+#define PEM_R_NO_START_LINE				 108
+#define PEM_R_PROBLEMS_GETTING_PASSWORD			 109
+#define PEM_R_PUBLIC_KEY_NO_RSA				 110
+#define PEM_R_READ_KEY					 111
+#define PEM_R_SHORT_HEADER				 112
+#define PEM_R_UNSUPPORTED_CIPHER			 113
+#define PEM_R_UNSUPPORTED_ENCRYPTION			 114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pem2.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pem2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pem2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,70 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+/*
+ * This header only exists to break a circular dependency between pem and err
+ * Ben 30 Jan 1999.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef HEADER_PEM_H
+void ERR_load_PEM_strings(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pkcs12.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pkcs12.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pkcs12.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,333 @@
+/* pkcs12.h */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_PKCS12_H
+#define HEADER_PKCS12_H
+
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PKCS12_KEY_ID	1
+#define PKCS12_IV_ID	2
+#define PKCS12_MAC_ID	3
+
+/* Default iteration count */
+#ifndef PKCS12_DEFAULT_ITER
+#define PKCS12_DEFAULT_ITER	PKCS5_DEFAULT_ITER
+#endif
+
+#define PKCS12_MAC_KEY_LENGTH 20
+
+#define PKCS12_SALT_LEN	8
+
+/* Uncomment out next line for unicode password and names, otherwise ASCII */
+
+/*#define PBE_UNICODE*/
+
+#ifdef PBE_UNICODE
+#define PKCS12_key_gen PKCS12_key_gen_uni
+#define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni
+#else
+#define PKCS12_key_gen PKCS12_key_gen_asc
+#define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
+#endif
+
+/* MS key usage constants */
+
+#define KEY_EX	0x10
+#define KEY_SIG 0x80
+
+typedef struct {
+X509_SIG *dinfo;
+ASN1_OCTET_STRING *salt;
+ASN1_INTEGER *iter;	/* defaults to 1 */
+} PKCS12_MAC_DATA;
+
+typedef struct {
+ASN1_INTEGER *version;
+PKCS12_MAC_DATA *mac;
+PKCS7 *authsafes;
+} PKCS12;
+
+PREDECLARE_STACK_OF(PKCS12_SAFEBAG)
+
+typedef struct {
+ASN1_OBJECT *type;
+union {
+	struct pkcs12_bag_st *bag; /* secret, crl and certbag */
+	struct pkcs8_priv_key_info_st	*keybag; /* keybag */
+	X509_SIG *shkeybag; /* shrouded key bag */
+	STACK_OF(PKCS12_SAFEBAG) *safes;
+	ASN1_TYPE *other;
+}value;
+STACK_OF(X509_ATTRIBUTE) *attrib;
+} PKCS12_SAFEBAG;
+
+DECLARE_STACK_OF(PKCS12_SAFEBAG)
+DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG)
+DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG)
+
+typedef struct pkcs12_bag_st {
+ASN1_OBJECT *type;
+union {
+	ASN1_OCTET_STRING *x509cert;
+	ASN1_OCTET_STRING *x509crl;
+	ASN1_OCTET_STRING *octet;
+	ASN1_IA5STRING *sdsicert;
+	ASN1_TYPE *other; /* Secret or other bag */
+}value;
+} PKCS12_BAGS;
+
+#define PKCS12_ERROR	0
+#define PKCS12_OK	1
+
+/* Compatibility macros */
+
+#define M_PKCS12_x5092certbag PKCS12_x5092certbag
+#define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag
+
+#define M_PKCS12_certbag2x509 PKCS12_certbag2x509
+#define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl 
+
+#define M_PKCS12_unpack_p7data PKCS12_unpack_p7data
+#define M_PKCS12_pack_authsafes PKCS12_pack_authsafes
+#define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes
+#define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata
+
+#define M_PKCS12_decrypt_skey PKCS12_decrypt_skey
+#define M_PKCS8_decrypt PKCS8_decrypt
+
+#define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type)
+#define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type)
+#define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type
+
+#define PKCS12_get_attr(bag, attr_nid) \
+			 PKCS12_get_attr_gen(bag->attrib, attr_nid)
+
+#define PKCS8_get_attr(p8, attr_nid) \
+		PKCS12_get_attr_gen(p8->attributes, attr_nid)
+
+#define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0)
+
+
+PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509);
+PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl);
+X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag);
+X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag);
+
+PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, int nid1,
+	     int nid2);
+PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, int passlen);
+PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, const char *pass,
+								int passlen);
+X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, 
+			const char *pass, int passlen,
+			unsigned char *salt, int saltlen, int iter,
+			PKCS8_PRIV_KEY_INFO *p8);
+PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
+				     int passlen, unsigned char *salt,
+				     int saltlen, int iter,
+				     PKCS8_PRIV_KEY_INFO *p8);
+PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7);
+PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
+			     unsigned char *salt, int saltlen, int iter,
+			     STACK_OF(PKCS12_SAFEBAG) *bags);
+STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, int passlen);
+
+int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes);
+STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12);
+
+int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, int namelen);
+int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
+				int namelen);
+int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
+				int namelen);
+int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, const unsigned char *name,
+				int namelen);
+int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage);
+ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid);
+char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag);
+unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
+				int passlen, unsigned char *in, int inlen,
+				unsigned char **data, int *datalen, int en_de);
+void * PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
+	     const char *pass, int passlen, ASN1_OCTET_STRING *oct, int zbuf);
+ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, const ASN1_ITEM *it,
+				       const char *pass, int passlen,
+				       void *obj, int zbuf);
+PKCS12 *PKCS12_init(int mode);
+int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
+		       int saltlen, int id, int iter, int n,
+		       unsigned char *out, const EVP_MD *md_type);
+int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, int saltlen, int id, int iter, int n, unsigned char *out, const EVP_MD *md_type);
+int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
+			 ASN1_TYPE *param, const EVP_CIPHER *cipher, const EVP_MD *md_type,
+			 int en_de);
+int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+			 unsigned char *mac, unsigned int *maclen);
+int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
+int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
+		   unsigned char *salt, int saltlen, int iter,
+		   const EVP_MD *md_type);
+int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
+					 int saltlen, const EVP_MD *md_type);
+unsigned char *asc2uni(const char *asc, int asclen, unsigned char **uni, int *unilen);
+char *uni2asc(unsigned char *uni, int unilen);
+
+DECLARE_ASN1_FUNCTIONS(PKCS12)
+DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
+DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
+DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS)
+
+DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS)
+DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES)
+
+void PKCS12_PBE_add(void);
+int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
+		 STACK_OF(X509) **ca);
+PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
+			 STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
+						 int mac_iter, int keytype);
+
+PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
+PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, EVP_PKEY *key,
+						int key_usage, int iter,
+						int key_nid, char *pass);
+int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
+					int safe_nid, int iter, char *pass);
+PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
+
+int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
+int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
+PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
+PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
+int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_PKCS12_strings(void);
+
+/* Error codes for the PKCS12 functions. */
+
+/* Function codes. */
+#define PKCS12_F_PARSE_BAG				 129
+#define PKCS12_F_PARSE_BAGS				 103
+#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME		 100
+#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC		 127
+#define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI		 102
+#define PKCS12_F_PKCS12_ADD_LOCALKEYID			 104
+#define PKCS12_F_PKCS12_CREATE				 105
+#define PKCS12_F_PKCS12_GEN_MAC				 107
+#define PKCS12_F_PKCS12_INIT				 109
+#define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I		 106
+#define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT		 108
+#define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG		 117
+#define PKCS12_F_PKCS12_KEY_GEN_ASC			 110
+#define PKCS12_F_PKCS12_KEY_GEN_UNI			 111
+#define PKCS12_F_PKCS12_MAKE_KEYBAG			 112
+#define PKCS12_F_PKCS12_MAKE_SHKEYBAG			 113
+#define PKCS12_F_PKCS12_NEWPASS				 128
+#define PKCS12_F_PKCS12_PACK_P7DATA			 114
+#define PKCS12_F_PKCS12_PACK_P7ENCDATA			 115
+#define PKCS12_F_PKCS12_PARSE				 118
+#define PKCS12_F_PKCS12_PBE_CRYPT			 119
+#define PKCS12_F_PKCS12_PBE_KEYIVGEN			 120
+#define PKCS12_F_PKCS12_SETUP_MAC			 122
+#define PKCS12_F_PKCS12_SET_MAC				 123
+#define PKCS12_F_PKCS12_UNPACK_AUTHSAFES		 130
+#define PKCS12_F_PKCS12_UNPACK_P7DATA			 131
+#define PKCS12_F_PKCS12_VERIFY_MAC			 126
+#define PKCS12_F_PKCS8_ADD_KEYUSAGE			 124
+#define PKCS12_F_PKCS8_ENCRYPT				 125
+
+/* Reason codes. */
+#define PKCS12_R_CANT_PACK_STRUCTURE			 100
+#define PKCS12_R_CONTENT_TYPE_NOT_DATA			 121
+#define PKCS12_R_DECODE_ERROR				 101
+#define PKCS12_R_ENCODE_ERROR				 102
+#define PKCS12_R_ENCRYPT_ERROR				 103
+#define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE	 120
+#define PKCS12_R_INVALID_NULL_ARGUMENT			 104
+#define PKCS12_R_INVALID_NULL_PKCS12_POINTER		 105
+#define PKCS12_R_IV_GEN_ERROR				 106
+#define PKCS12_R_KEY_GEN_ERROR				 107
+#define PKCS12_R_MAC_ABSENT				 108
+#define PKCS12_R_MAC_GENERATION_ERROR			 109
+#define PKCS12_R_MAC_SETUP_ERROR			 110
+#define PKCS12_R_MAC_STRING_SET_ERROR			 111
+#define PKCS12_R_MAC_VERIFY_ERROR			 112
+#define PKCS12_R_MAC_VERIFY_FAILURE			 113
+#define PKCS12_R_PARSE_ERROR				 114
+#define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR		 115
+#define PKCS12_R_PKCS12_CIPHERFINAL_ERROR		 116
+#define PKCS12_R_PKCS12_PBE_CRYPT_ERROR			 117
+#define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM		 118
+#define PKCS12_R_UNSUPPORTED_PKCS12_MODE		 119
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pkcs7.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pkcs7.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pkcs7.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,463 @@
+/* crypto/pkcs7/pkcs7.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_PKCS7_H
+#define HEADER_PKCS7_H
+
+#include <openssl/asn1.h>
+#include <openssl/bio.h>
+#include <openssl/e_os2.h>
+
+#include <openssl/symhacks.h>
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+/* Under Win32 thes are defined in wincrypt.h */
+#undef PKCS7_ISSUER_AND_SERIAL
+#undef PKCS7_SIGNER_INFO
+#endif
+
+/*
+Encryption_ID		DES-CBC
+Digest_ID		MD5
+Digest_Encryption_ID	rsaEncryption
+Key_Encryption_ID	rsaEncryption
+*/
+
+typedef struct pkcs7_issuer_and_serial_st
+	{
+	X509_NAME *issuer;
+	ASN1_INTEGER *serial;
+	} PKCS7_ISSUER_AND_SERIAL;
+
+typedef struct pkcs7_signer_info_st
+	{
+	ASN1_INTEGER 			*version;	/* version 1 */
+	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
+	X509_ALGOR			*digest_alg;
+	STACK_OF(X509_ATTRIBUTE)	*auth_attr;	/* [ 0 ] */
+	X509_ALGOR			*digest_enc_alg;
+	ASN1_OCTET_STRING		*enc_digest;
+	STACK_OF(X509_ATTRIBUTE)	*unauth_attr;	/* [ 1 ] */
+
+	/* The private key to sign with */
+	EVP_PKEY			*pkey;
+	} PKCS7_SIGNER_INFO;
+
+DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO)
+
+typedef struct pkcs7_recip_info_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	PKCS7_ISSUER_AND_SERIAL		*issuer_and_serial;
+	X509_ALGOR			*key_enc_algor;
+	ASN1_OCTET_STRING		*enc_key;
+	X509				*cert; /* get the pub-key from this */
+	} PKCS7_RECIP_INFO;
+
+DECLARE_STACK_OF(PKCS7_RECIP_INFO)
+DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO)
+
+typedef struct pkcs7_signed_st
+	{
+	ASN1_INTEGER			*version;	/* version 1 */
+	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
+	STACK_OF(X509)			*cert;		/* [ 0 ] */
+	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
+	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
+
+	struct pkcs7_st			*contents;
+	} PKCS7_SIGNED;
+/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE.
+ * How about merging the two */
+
+typedef struct pkcs7_enc_content_st
+	{
+	ASN1_OBJECT			*content_type;
+	X509_ALGOR			*algorithm;
+	ASN1_OCTET_STRING		*enc_data;	/* [ 0 ] */
+	const EVP_CIPHER		*cipher;
+	} PKCS7_ENC_CONTENT;
+
+typedef struct pkcs7_enveloped_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
+	PKCS7_ENC_CONTENT		*enc_data;
+	} PKCS7_ENVELOPE;
+
+typedef struct pkcs7_signedandenveloped_st
+	{
+	ASN1_INTEGER			*version;	/* version 1 */
+	STACK_OF(X509_ALGOR)		*md_algs;	/* md used */
+	STACK_OF(X509)			*cert;		/* [ 0 ] */
+	STACK_OF(X509_CRL)		*crl;		/* [ 1 ] */
+	STACK_OF(PKCS7_SIGNER_INFO)	*signer_info;
+
+	PKCS7_ENC_CONTENT		*enc_data;
+	STACK_OF(PKCS7_RECIP_INFO)	*recipientinfo;
+	} PKCS7_SIGN_ENVELOPE;
+
+typedef struct pkcs7_digest_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	X509_ALGOR			*md;		/* md used */
+	struct pkcs7_st 		*contents;
+	ASN1_OCTET_STRING		*digest;
+	} PKCS7_DIGEST;
+
+typedef struct pkcs7_encrypted_st
+	{
+	ASN1_INTEGER			*version;	/* version 0 */
+	PKCS7_ENC_CONTENT		*enc_data;
+	} PKCS7_ENCRYPT;
+
+typedef struct pkcs7_st
+	{
+	/* The following is non NULL if it contains ASN1 encoding of
+	 * this structure */
+	unsigned char *asn1;
+	long length;
+
+#define PKCS7_S_HEADER	0
+#define PKCS7_S_BODY	1
+#define PKCS7_S_TAIL	2
+	int state; /* used during processing */
+
+	int detached;
+
+	ASN1_OBJECT *type;
+	/* content as defined by the type */
+	/* all encryption/message digests are applied to the 'contents',
+	 * leaving out the 'type' field. */
+	union	{
+		char *ptr;
+
+		/* NID_pkcs7_data */
+		ASN1_OCTET_STRING *data;
+
+		/* NID_pkcs7_signed */
+		PKCS7_SIGNED *sign;
+
+		/* NID_pkcs7_enveloped */
+		PKCS7_ENVELOPE *enveloped;
+
+		/* NID_pkcs7_signedAndEnveloped */
+		PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
+
+		/* NID_pkcs7_digest */
+		PKCS7_DIGEST *digest;
+
+		/* NID_pkcs7_encrypted */
+		PKCS7_ENCRYPT *encrypted;
+
+		/* Anything else */
+		ASN1_TYPE *other;
+		} d;
+	} PKCS7;
+
+DECLARE_STACK_OF(PKCS7)
+DECLARE_ASN1_SET_OF(PKCS7)
+DECLARE_PKCS12_STACK_OF(PKCS7)
+
+#define PKCS7_OP_SET_DETACHED_SIGNATURE	1
+#define PKCS7_OP_GET_DETACHED_SIGNATURE	2
+
+#define PKCS7_get_signed_attributes(si)	((si)->auth_attr)
+#define PKCS7_get_attributes(si)	((si)->unauth_attr)
+
+#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
+#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
+#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
+#define PKCS7_type_is_signedAndEnveloped(a) \
+		(OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
+#define PKCS7_type_is_data(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
+
+#define PKCS7_type_is_digest(a)   (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
+
+#define PKCS7_set_detached(p,v) \
+		PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
+#define PKCS7_get_detached(p) \
+		PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
+
+#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
+
+#ifdef SSLEAY_MACROS
+#ifndef PKCS7_ISSUER_AND_SERIAL_digest
+#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
+        ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
+	                (char *)data,md,len)
+#endif
+#endif
+
+/* S/MIME related flags */
+
+#define PKCS7_TEXT		0x1
+#define PKCS7_NOCERTS		0x2
+#define PKCS7_NOSIGS		0x4
+#define PKCS7_NOCHAIN		0x8
+#define PKCS7_NOINTERN		0x10
+#define PKCS7_NOVERIFY		0x20
+#define PKCS7_DETACHED		0x40
+#define PKCS7_BINARY		0x80
+#define PKCS7_NOATTR		0x100
+#define	PKCS7_NOSMIMECAP	0x200
+#define PKCS7_NOOLDMIMETYPE	0x400
+#define PKCS7_CRLFEOL		0x800
+#define PKCS7_STREAM		0x1000
+#define PKCS7_NOCRL		0x2000
+
+/* Flags: for compatibility with older code */
+
+#define SMIME_TEXT	PKCS7_TEXT
+#define SMIME_NOCERTS	PKCS7_NOCERTS
+#define SMIME_NOSIGS	PKCS7_NOSIGS
+#define SMIME_NOCHAIN	PKCS7_NOCHAIN
+#define SMIME_NOINTERN	PKCS7_NOINTERN
+#define SMIME_NOVERIFY	PKCS7_NOVERIFY
+#define SMIME_DETACHED	PKCS7_DETACHED
+#define SMIME_BINARY	PKCS7_BINARY
+#define SMIME_NOATTR	PKCS7_NOATTR
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
+
+#ifndef SSLEAY_MACROS
+int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
+	unsigned char *md,unsigned int *len);
+#ifndef OPENSSL_NO_FP_API
+PKCS7 *d2i_PKCS7_fp(FILE *fp,PKCS7 **p7);
+int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7);
+#endif
+PKCS7 *PKCS7_dup(PKCS7 *p7);
+PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
+int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
+#endif
+
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE)
+DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST)
+DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT)
+DECLARE_ASN1_FUNCTIONS(PKCS7)
+
+DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
+DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
+
+DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
+
+long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
+
+int PKCS7_set_type(PKCS7 *p7, int type);
+int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
+int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
+int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
+	const EVP_MD *dgst);
+int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
+int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
+int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
+int PKCS7_content_new(PKCS7 *p7, int nid);
+int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
+	BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); 
+int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
+								X509 *x509);
+
+BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
+int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
+
+
+PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
+	EVP_PKEY *pkey, const EVP_MD *dgst);
+X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
+STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
+
+PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
+int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
+int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
+
+PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
+ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si,int nid,int type,
+	void *data);
+int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
+	void *value);
+ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
+ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
+int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
+				STACK_OF(X509_ATTRIBUTE) *sk);
+int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
+
+
+PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
+							BIO *data, int flags);
+int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
+					BIO *indata, BIO *out, int flags);
+STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
+PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
+								int flags);
+int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
+
+int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
+			      STACK_OF(X509_ALGOR) *cap);
+STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
+int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
+
+int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
+PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
+int SMIME_crlf_copy(BIO *in, BIO *out, int flags);
+int SMIME_text(BIO *in, BIO *out);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_PKCS7_strings(void);
+
+/* Error codes for the PKCS7 functions. */
+
+/* Function codes. */
+#define PKCS7_F_B64_READ_PKCS7				 120
+#define PKCS7_F_B64_WRITE_PKCS7				 121
+#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP		 118
+#define PKCS7_F_PKCS7_ADD_CERTIFICATE			 100
+#define PKCS7_F_PKCS7_ADD_CRL				 101
+#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO		 102
+#define PKCS7_F_PKCS7_ADD_SIGNER			 103
+#define PKCS7_F_PKCS7_BIO_ADD_DIGEST			 125
+#define PKCS7_F_PKCS7_CTRL				 104
+#define PKCS7_F_PKCS7_DATADECODE			 112
+#define PKCS7_F_PKCS7_DATAFINAL				 128
+#define PKCS7_F_PKCS7_DATAINIT				 105
+#define PKCS7_F_PKCS7_DATASIGN				 106
+#define PKCS7_F_PKCS7_DATAVERIFY			 107
+#define PKCS7_F_PKCS7_DECRYPT				 114
+#define PKCS7_F_PKCS7_ENCRYPT				 115
+#define PKCS7_F_PKCS7_FIND_DIGEST			 127
+#define PKCS7_F_PKCS7_GET0_SIGNERS			 124
+#define PKCS7_F_PKCS7_SET_CIPHER			 108
+#define PKCS7_F_PKCS7_SET_CONTENT			 109
+#define PKCS7_F_PKCS7_SET_DIGEST			 126
+#define PKCS7_F_PKCS7_SET_TYPE				 110
+#define PKCS7_F_PKCS7_SIGN				 116
+#define PKCS7_F_PKCS7_SIGNATUREVERIFY			 113
+#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP			 119
+#define PKCS7_F_PKCS7_VERIFY				 117
+#define PKCS7_F_SMIME_READ_PKCS7			 122
+#define PKCS7_F_SMIME_TEXT				 123
+
+/* Reason codes. */
+#define PKCS7_R_CERTIFICATE_VERIFY_ERROR		 117
+#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER		 144
+#define PKCS7_R_CIPHER_NOT_INITIALIZED			 116
+#define PKCS7_R_CONTENT_AND_DATA_PRESENT		 118
+#define PKCS7_R_DECODE_ERROR				 130
+#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH		 100
+#define PKCS7_R_DECRYPT_ERROR				 119
+#define PKCS7_R_DIGEST_FAILURE				 101
+#define PKCS7_R_ERROR_ADDING_RECIPIENT			 120
+#define PKCS7_R_ERROR_SETTING_CIPHER			 121
+#define PKCS7_R_INVALID_MIME_TYPE			 131
+#define PKCS7_R_INVALID_NULL_POINTER			 143
+#define PKCS7_R_MIME_NO_CONTENT_TYPE			 132
+#define PKCS7_R_MIME_PARSE_ERROR			 133
+#define PKCS7_R_MIME_SIG_PARSE_ERROR			 134
+#define PKCS7_R_MISSING_CERIPEND_INFO			 103
+#define PKCS7_R_NO_CONTENT				 122
+#define PKCS7_R_NO_CONTENT_TYPE				 135
+#define PKCS7_R_NO_MULTIPART_BODY_FAILURE		 136
+#define PKCS7_R_NO_MULTIPART_BOUNDARY			 137
+#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE	 115
+#define PKCS7_R_NO_SIGNATURES_ON_DATA			 123
+#define PKCS7_R_NO_SIGNERS				 142
+#define PKCS7_R_NO_SIG_CONTENT_TYPE			 138
+#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE	 104
+#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR		 124
+#define PKCS7_R_PKCS7_DATAFINAL				 126
+#define PKCS7_R_PKCS7_DATAFINAL_ERROR			 125
+#define PKCS7_R_PKCS7_DATASIGN				 145
+#define PKCS7_R_PKCS7_PARSE_ERROR			 139
+#define PKCS7_R_PKCS7_SIG_PARSE_ERROR			 140
+#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE	 127
+#define PKCS7_R_SIGNATURE_FAILURE			 105
+#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND		 128
+#define PKCS7_R_SIG_INVALID_MIME_TYPE			 141
+#define PKCS7_R_SMIME_TEXT_ERROR			 129
+#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE		 106
+#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO			 107
+#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST		 108
+#define PKCS7_R_UNKNOWN_DIGEST_TYPE			 109
+#define PKCS7_R_UNKNOWN_OPERATION			 110
+#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE			 111
+#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE		 112
+#define PKCS7_R_WRONG_CONTENT_TYPE			 113
+#define PKCS7_R_WRONG_PKCS7_TYPE			 114
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pq_compat.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pq_compat.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pq_compat.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,147 @@
+/* crypto/pqueue/pqueue_compat.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "opensslconf.h"
+#include <openssl/bn.h>
+
+/* 
+ * The purpose of this header file is for supporting 64-bit integer
+ * manipulation on 32-bit (and lower) machines.  Currently the only
+ * such environment is VMS, Utrix and those with smaller default integer
+ * sizes than 32 bits.  For all such environment, we fall back to using
+ * BIGNUM.  We may need to fine tune the conditions for systems that
+ * are incorrectly configured.
+ *
+ * The only clients of this code are (1) pqueue for priority, and
+ * (2) DTLS, for sequence number manipulation.
+ */
+
+#if (defined(THIRTY_TWO_BIT) && !defined(BN_LLONG)) || defined(SIXTEEN_BIT) || defined(EIGHT_BIT)
+
+#define PQ_64BIT_IS_INTEGER 0
+#define PQ_64BIT_IS_BIGNUM 1
+
+#define PQ_64BIT     BIGNUM
+#define PQ_64BIT_CTX BN_CTX
+
+#define pq_64bit_init(x)           BN_init(x)
+#define pq_64bit_free(x)           BN_free(x)
+
+#define pq_64bit_ctx_new(ctx)      BN_CTX_new()
+#define pq_64bit_ctx_free(x)       BN_CTX_free(x)
+
+#define pq_64bit_assign(x, y)      BN_copy(x, y)
+#define pq_64bit_assign_word(x, y) BN_set_word(x, y)
+#define pq_64bit_gt(x, y)          BN_ucmp(x, y) >= 1 ? 1 : 0
+#define pq_64bit_eq(x, y)          BN_ucmp(x, y) == 0 ? 1 : 0
+#define pq_64bit_add_word(x, w)    BN_add_word(x, w)
+#define pq_64bit_sub(r, x, y)      BN_sub(r, x, y)
+#define pq_64bit_sub_word(x, w)    BN_sub_word(x, w)
+#define pq_64bit_mod(r, x, n, ctx) BN_mod(r, x, n, ctx)
+
+#define pq_64bit_bin2num(bn, bytes, len)   BN_bin2bn(bytes, len, bn)
+#define pq_64bit_num2bin(bn, bytes)        BN_bn2bin(bn, bytes)
+#define pq_64bit_get_word(x)               BN_get_word(x)
+#define pq_64bit_is_bit_set(x, offset)     BN_is_bit_set(x, offset)
+#define pq_64bit_lshift(r, x, shift)       BN_lshift(r, x, shift)
+#define pq_64bit_set_bit(x, num)           BN_set_bit(x, num)
+#define pq_64bit_get_length(x)             BN_num_bits((x))
+
+#else
+
+#define PQ_64BIT_IS_INTEGER 1
+#define PQ_64BIT_IS_BIGNUM 0
+
+#if defined(SIXTY_FOUR_BIT)
+#define PQ_64BIT BN_ULONG
+#define PQ_64BIT_PRINT "%lld"
+#elif defined(SIXTY_FOUR_BIT_LONG)
+#define PQ_64BIT BN_ULONG
+#define PQ_64BIT_PRINT "%ld"
+#elif defined(THIRTY_TWO_BIT)
+#define PQ_64BIT BN_ULLONG
+#define PQ_64BIT_PRINT "%lld"
+#endif
+
+#define PQ_64BIT_CTX      void
+
+#define pq_64bit_init(x)
+#define pq_64bit_free(x)
+#define pq_64bit_ctx_new(ctx)        (ctx)
+#define pq_64bit_ctx_free(x)
+
+#define pq_64bit_assign(x, y)        (*(x) = *(y))
+#define pq_64bit_assign_word(x, y)   (*(x) = y)
+#define pq_64bit_gt(x, y)	         (*(x) > *(y))
+#define pq_64bit_eq(x, y)            (*(x) == *(y))
+#define pq_64bit_add_word(x, w)      (*(x) = (*(x) + (w)))
+#define pq_64bit_sub(r, x, y)        (*(r) = (*(x) - *(y)))
+#define pq_64bit_sub_word(x, w)      (*(x) = (*(x) - (w)))
+#define pq_64bit_mod(r, x, n, ctx)
+
+#define pq_64bit_bin2num(num, bytes, len) bytes_to_long_long(bytes, num)
+#define pq_64bit_num2bin(num, bytes)      long_long_to_bytes(num, bytes)
+#define pq_64bit_get_word(x)              *(x)
+#define pq_64bit_lshift(r, x, shift)      (*(r) = (*(x) << (shift)))
+#define pq_64bit_set_bit(x, num)          do { \
+                                              PQ_64BIT mask = 1; \
+                                              mask = mask << (num); \
+                                              *(x) |= mask; \
+                                          } while(0)
+#endif /* OPENSSL_SYS_VMS */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pqueue.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pqueue.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/pqueue.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,95 @@
+/* crypto/pqueue/pqueue.h */
+/* 
+ * DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_PQUEUE_H
+#define HEADER_PQUEUE_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/pq_compat.h>
+
+typedef struct _pqueue *pqueue;
+
+typedef struct _pitem
+	{
+	PQ_64BIT priority;
+	void *data;
+	struct _pitem *next;
+	} pitem;
+
+typedef struct _pitem *piterator;
+
+pitem *pitem_new(PQ_64BIT priority, void *data);
+void   pitem_free(pitem *item);
+
+pqueue pqueue_new(void);
+void   pqueue_free(pqueue pq);
+
+pitem *pqueue_insert(pqueue pq, pitem *item);
+pitem *pqueue_peek(pqueue pq);
+pitem *pqueue_pop(pqueue pq);
+pitem *pqueue_find(pqueue pq, PQ_64BIT priority);
+pitem *pqueue_iterator(pqueue pq);
+pitem *pqueue_next(piterator *iter);
+
+void   pqueue_print(pqueue pq);
+
+#endif /* ! HEADER_PQUEUE_H */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rand.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rand.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rand.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,140 @@
+/* crypto/rand/rand.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RAND_H
+#define HEADER_RAND_H
+
+#include <stdlib.h>
+#include <openssl/ossl_typ.h>
+#include <openssl/e_os2.h>
+
+#if defined(OPENSSL_SYS_WINDOWS)
+#include <windows.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(OPENSSL_FIPS)
+#define FIPS_RAND_SIZE_T size_t
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct rand_meth_st RAND_METHOD; */
+
+struct rand_meth_st
+	{
+	void (*seed)(const void *buf, int num);
+	int (*bytes)(unsigned char *buf, int num);
+	void (*cleanup)(void);
+	void (*add)(const void *buf, int num, double entropy);
+	int (*pseudorand)(unsigned char *buf, int num);
+	int (*status)(void);
+	};
+
+#ifdef BN_DEBUG
+extern int rand_predictable;
+#endif
+
+int RAND_set_rand_method(const RAND_METHOD *meth);
+const RAND_METHOD *RAND_get_rand_method(void);
+#ifndef OPENSSL_NO_ENGINE
+int RAND_set_rand_engine(ENGINE *engine);
+#endif
+RAND_METHOD *RAND_SSLeay(void);
+void RAND_cleanup(void );
+int  RAND_bytes(unsigned char *buf,int num);
+int  RAND_pseudo_bytes(unsigned char *buf,int num);
+void RAND_seed(const void *buf,int num);
+void RAND_add(const void *buf,int num,double entropy);
+int  RAND_load_file(const char *file,long max_bytes);
+int  RAND_write_file(const char *file);
+const char *RAND_file_name(char *file,size_t num);
+int RAND_status(void);
+int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
+int RAND_egd(const char *path);
+int RAND_egd_bytes(const char *path,int bytes);
+int RAND_poll(void);
+
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
+
+void RAND_screen(void);
+int RAND_event(UINT, WPARAM, LPARAM);
+
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_RAND_strings(void);
+
+/* Error codes for the RAND functions. */
+
+/* Function codes. */
+#define RAND_F_RAND_GET_RAND_METHOD			 101
+#define RAND_F_SSLEAY_RAND_BYTES			 100
+
+/* Reason codes. */
+#define RAND_R_PRNG_NOT_SEEDED				 100
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rc2.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rc2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rc2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,101 @@
+/* crypto/rc2/rc2.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC2_H
+#define HEADER_RC2_H
+
+#include <openssl/opensslconf.h> /* OPENSSL_NO_RC2, RC2_INT */
+#ifdef OPENSSL_NO_RC2
+#error RC2 is disabled.
+#endif
+
+#define RC2_ENCRYPT	1
+#define RC2_DECRYPT	0
+
+#define RC2_BLOCK	8
+#define RC2_KEY_LENGTH	16
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc2_key_st
+	{
+	RC2_INT data[64];
+	} RC2_KEY;
+
+ 
+void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data,int bits);
+void RC2_ecb_encrypt(const unsigned char *in,unsigned char *out,RC2_KEY *key,
+		     int enc);
+void RC2_encrypt(unsigned long *data,RC2_KEY *key);
+void RC2_decrypt(unsigned long *data,RC2_KEY *key);
+void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
+	RC2_KEY *ks, unsigned char *iv, int enc);
+void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num, int enc);
+void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+		       long length, RC2_KEY *schedule, unsigned char *ivec,
+		       int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rc4.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rc4.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rc4.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,87 @@
+/* crypto/rc4/rc4.h */
+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC4_H
+#define HEADER_RC4_H
+
+#include <openssl/opensslconf.h> /* OPENSSL_NO_RC4, RC4_INT */
+#ifdef OPENSSL_NO_RC4
+#error RC4 is disabled.
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct rc4_key_st
+	{
+	RC4_INT x,y;
+	RC4_INT data[256];
+	} RC4_KEY;
+
+ 
+const char *RC4_options(void);
+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
+		unsigned char *outdata);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rc5.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rc5.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rc5.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,120 @@
+/* crypto/rc5/rc5.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RC5_H
+#define HEADER_RC5_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_RC5
+#error RC5 is disabled.
+#endif
+
+#define RC5_ENCRYPT	1
+#define RC5_DECRYPT	0
+
+/* 32 bit.  For Alpha, things may get weird */
+#define RC5_32_INT unsigned long
+
+#define RC5_32_BLOCK		8
+#define RC5_32_KEY_LENGTH	16 /* This is a default, max is 255 */
+
+/* This are the only values supported.  Tweak the code if you want more
+ * The most supported modes will be
+ * RC5-32/12/16
+ * RC5-32/16/8
+ */
+#define RC5_8_ROUNDS	8
+#define RC5_12_ROUNDS	12
+#define RC5_16_ROUNDS	16
+
+typedef struct rc5_key_st
+	{
+	/* Number of rounds */
+	int rounds;
+	RC5_32_INT data[2*(RC5_16_ROUNDS+1)];
+	} RC5_32_KEY;
+
+#ifdef OPENSSL_FIPS 
+void private_RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
+	int rounds);
+#endif
+void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data,
+	int rounds);
+void RC5_32_ecb_encrypt(const unsigned char *in,unsigned char *out,RC5_32_KEY *key,
+	int enc);
+void RC5_32_encrypt(unsigned long *data,RC5_32_KEY *key);
+void RC5_32_decrypt(unsigned long *data,RC5_32_KEY *key);
+void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out,
+			long length, RC5_32_KEY *ks, unsigned char *iv,
+			int enc);
+void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out,
+			  long length, RC5_32_KEY *schedule,
+			  unsigned char *ivec, int *num, int enc);
+void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out,
+			  long length, RC5_32_KEY *schedule,
+			  unsigned char *ivec, int *num);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ripemd.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ripemd.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ripemd.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,103 @@
+/* crypto/ripemd/ripemd.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RIPEMD_H
+#define HEADER_RIPEMD_H
+
+#include <openssl/e_os2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_NO_RIPEMD
+#error RIPEMD is disabled.
+#endif
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define RIPEMD160_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define RIPEMD160_LONG unsigned long
+#define RIPEMD160_LONG_LOG2 3
+#else
+#define RIPEMD160_LONG unsigned int
+#endif
+
+#define RIPEMD160_CBLOCK	64
+#define RIPEMD160_LBLOCK	(RIPEMD160_CBLOCK/4)
+#define RIPEMD160_DIGEST_LENGTH	20
+
+typedef struct RIPEMD160state_st
+	{
+	RIPEMD160_LONG A,B,C,D,E;
+	RIPEMD160_LONG Nl,Nh;
+	RIPEMD160_LONG data[RIPEMD160_LBLOCK];
+	unsigned int   num;
+	} RIPEMD160_CTX;
+
+int RIPEMD160_Init(RIPEMD160_CTX *c);
+int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len);
+int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c);
+unsigned char *RIPEMD160(const unsigned char *d, size_t n,
+	unsigned char *md);
+void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b);
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rsa.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rsa.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/rsa.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,429 @@
+/* crypto/rsa/rsa.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_RSA_H
+#define HEADER_RSA_H
+
+#include <openssl/asn1.h>
+
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/crypto.h>
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/bn.h>
+#endif
+
+#ifdef OPENSSL_NO_RSA
+#error RSA is disabled.
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Declared already in ossl_typ.h */
+/* typedef struct rsa_st RSA; */
+/* typedef struct rsa_meth_st RSA_METHOD; */
+
+struct rsa_meth_st
+	{
+	const char *name;
+	int (*rsa_pub_enc)(int flen,const unsigned char *from,
+			   unsigned char *to,
+			   RSA *rsa,int padding);
+	int (*rsa_pub_dec)(int flen,const unsigned char *from,
+			   unsigned char *to,
+			   RSA *rsa,int padding);
+	int (*rsa_priv_enc)(int flen,const unsigned char *from,
+			    unsigned char *to,
+			    RSA *rsa,int padding);
+	int (*rsa_priv_dec)(int flen,const unsigned char *from,
+			    unsigned char *to,
+			    RSA *rsa,int padding);
+	int (*rsa_mod_exp)(BIGNUM *r0,const BIGNUM *I,RSA *rsa,BN_CTX *ctx); /* Can be null */
+	int (*bn_mod_exp)(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+			  const BIGNUM *m, BN_CTX *ctx,
+			  BN_MONT_CTX *m_ctx); /* Can be null */
+	int (*init)(RSA *rsa);		/* called at new */
+	int (*finish)(RSA *rsa);	/* called at free */
+	int flags;			/* RSA_METHOD_FLAG_* things */
+	char *app_data;			/* may be needed! */
+/* New sign and verify functions: some libraries don't allow arbitrary data
+ * to be signed/verified: this allows them to be used. Note: for this to work
+ * the RSA_public_decrypt() and RSA_private_encrypt() should *NOT* be used
+ * RSA_sign(), RSA_verify() should be used instead. Note: for backwards
+ * compatibility this functionality is only enabled if the RSA_FLAG_SIGN_VER
+ * option is set in 'flags'.
+ */
+	int (*rsa_sign)(int type,
+		const unsigned char *m, unsigned int m_length,
+		unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
+	int (*rsa_verify)(int dtype,
+		const unsigned char *m, unsigned int m_length,
+		unsigned char *sigbuf, unsigned int siglen, const RSA *rsa);
+/* If this callback is NULL, the builtin software RSA key-gen will be used. This
+ * is for behavioural compatibility whilst the code gets rewired, but one day
+ * it would be nice to assume there are no such things as "builtin software"
+ * implementations. */
+	int (*rsa_keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+	};
+
+struct rsa_st
+	{
+	/* The first parameter is used to pickup errors where
+	 * this is passed instead of aEVP_PKEY, it is set to 0 */
+	int pad;
+	long version;
+	const RSA_METHOD *meth;
+	/* functional reference if 'meth' is ENGINE-provided */
+	ENGINE *engine;
+	BIGNUM *n;
+	BIGNUM *e;
+	BIGNUM *d;
+	BIGNUM *p;
+	BIGNUM *q;
+	BIGNUM *dmp1;
+	BIGNUM *dmq1;
+	BIGNUM *iqmp;
+	/* be careful using this if the RSA structure is shared */
+	CRYPTO_EX_DATA ex_data;
+	int references;
+	int flags;
+
+	/* Used to cache montgomery values */
+	BN_MONT_CTX *_method_mod_n;
+	BN_MONT_CTX *_method_mod_p;
+	BN_MONT_CTX *_method_mod_q;
+
+	/* all BIGNUM values are actually in the following data, if it is not
+	 * NULL */
+	char *bignum_data;
+	BN_BLINDING *blinding;
+	BN_BLINDING *mt_blinding;
+	};
+
+#define RSA_3	0x3L
+#define RSA_F4	0x10001L
+
+#define RSA_METHOD_FLAG_NO_CHECK	0x0001 /* don't check pub/private match */
+
+#define RSA_FLAG_CACHE_PUBLIC		0x0002
+#define RSA_FLAG_CACHE_PRIVATE		0x0004
+#define RSA_FLAG_BLINDING		0x0008
+#define RSA_FLAG_THREAD_SAFE		0x0010
+/* This flag means the private key operations will be handled by rsa_mod_exp
+ * and that they do not depend on the private key components being present:
+ * for example a key stored in external hardware. Without this flag bn_mod_exp
+ * gets called when private key components are absent.
+ */
+#define RSA_FLAG_EXT_PKEY		0x0020
+
+/* This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify functions.
+ */
+#define RSA_FLAG_SIGN_VER		0x0040
+
+#define RSA_FLAG_NO_BLINDING		0x0080 /* new with 0.9.6j and 0.9.7b; the built-in
+                                                * RSA implementation now uses blinding by
+                                                * default (ignoring RSA_FLAG_BLINDING),
+                                                * but other engines might not need it
+                                                */
+#define RSA_FLAG_NO_EXP_CONSTTIME	0x0100 /* new with 0.9.7h; the built-in RSA
+                                                * implementation now uses constant time
+                                                * modular exponentiation for secret exponents
+                                                * by default. This flag causes the
+                                                * faster variable sliding window method to
+                                                * be used for all exponents.
+                                                */
+
+#define RSA_PKCS1_PADDING	1
+#define RSA_SSLV23_PADDING	2
+#define RSA_NO_PADDING		3
+#define RSA_PKCS1_OAEP_PADDING	4
+#define RSA_X931_PADDING	5
+
+#define RSA_PKCS1_PADDING_SIZE	11
+
+#define RSA_set_app_data(s,arg)         RSA_set_ex_data(s,0,arg)
+#define RSA_get_app_data(s)             RSA_get_ex_data(s,0)
+
+RSA *	RSA_new(void);
+RSA *	RSA_new_method(ENGINE *engine);
+int	RSA_size(const RSA *);
+
+/* Deprecated version */
+#ifndef OPENSSL_NO_DEPRECATED
+RSA *	RSA_generate_key(int bits, unsigned long e,void
+		(*callback)(int,int,void *),void *cb_arg);
+#endif /* !defined(OPENSSL_NO_DEPRECATED) */
+
+/* New version */
+int	RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+
+int	RSA_check_key(const RSA *);
+	/* next 4 return -1 on error */
+int	RSA_public_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_private_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_public_decrypt(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa,int padding);
+int	RSA_private_decrypt(int flen, const unsigned char *from, 
+		unsigned char *to, RSA *rsa,int padding);
+void	RSA_free (RSA *r);
+/* "up" the RSA object's reference count */
+int	RSA_up_ref(RSA *r);
+
+int	RSA_flags(const RSA *r);
+
+void RSA_set_default_method(const RSA_METHOD *meth);
+const RSA_METHOD *RSA_get_default_method(void);
+const RSA_METHOD *RSA_get_method(const RSA *rsa);
+int RSA_set_method(RSA *rsa, const RSA_METHOD *meth);
+
+/* This function needs the memory locking malloc callbacks to be installed */
+int RSA_memory_lock(RSA *r);
+
+/* these are the actual SSLeay RSA functions */
+const RSA_METHOD *RSA_PKCS1_SSLeay(void);
+
+const RSA_METHOD *RSA_null_method(void);
+
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
+DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
+
+#ifndef OPENSSL_NO_FP_API
+int	RSA_print_fp(FILE *fp, const RSA *r,int offset);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+int	RSA_print(BIO *bp, const RSA *r,int offset);
+#endif
+
+int i2d_RSA_NET(const RSA *a, unsigned char **pp,
+		int (*cb)(char *buf, int len, const char *prompt, int verify),
+		int sgckey);
+RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
+		 int (*cb)(char *buf, int len, const char *prompt, int verify),
+		 int sgckey);
+
+int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
+		     int (*cb)(char *buf, int len, const char *prompt,
+			       int verify));
+RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
+		      int (*cb)(char *buf, int len, const char *prompt,
+				int verify));
+
+/* The following 2 functions sign and verify a X509_SIG ASN1 object
+ * inside PKCS#1 padded RSA encryption */
+int RSA_sign(int type, const unsigned char *m, unsigned int m_length,
+	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify(int type, const unsigned char *m, unsigned int m_length,
+	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+/* The following 2 function sign and verify a ASN1_OCTET_STRING
+ * object inside PKCS#1 padded RSA encryption */
+int RSA_sign_ASN1_OCTET_STRING(int type,
+	const unsigned char *m, unsigned int m_length,
+	unsigned char *sigret, unsigned int *siglen, RSA *rsa);
+int RSA_verify_ASN1_OCTET_STRING(int type,
+	const unsigned char *m, unsigned int m_length,
+	unsigned char *sigbuf, unsigned int siglen, RSA *rsa);
+
+int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+void RSA_blinding_off(RSA *rsa);
+BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx);
+
+int RSA_padding_add_PKCS1_type_1(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_PKCS1_type_1(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_PKCS1_type_2(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_PKCS1_type_2(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int PKCS1_MGF1(unsigned char *mask, long len,
+	const unsigned char *seed, long seedlen, const EVP_MD *dgst);
+int RSA_padding_add_PKCS1_OAEP(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,
+	const unsigned char *p,int pl);
+int RSA_padding_check_PKCS1_OAEP(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len,
+	const unsigned char *p,int pl);
+int RSA_padding_add_SSLv23(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_SSLv23(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_none(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_none(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_padding_add_X931(unsigned char *to,int tlen,
+	const unsigned char *f,int fl);
+int RSA_padding_check_X931(unsigned char *to,int tlen,
+	const unsigned char *f,int fl,int rsa_len);
+int RSA_X931_hash_id(int nid);
+
+int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash,
+			const EVP_MD *Hash, const unsigned char *EM, int sLen);
+int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM,
+			const unsigned char *mHash,
+			const EVP_MD *Hash, int sLen);
+
+int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int RSA_set_ex_data(RSA *r,int idx,void *arg);
+void *RSA_get_ex_data(const RSA *r, int idx);
+
+RSA *RSAPublicKey_dup(RSA *rsa);
+RSA *RSAPrivateKey_dup(RSA *rsa);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_RSA_strings(void);
+
+/* Error codes for the RSA functions. */
+
+/* Function codes. */
+#define RSA_F_MEMORY_LOCK				 100
+#define RSA_F_RSA_BUILTIN_KEYGEN			 129
+#define RSA_F_RSA_CHECK_KEY				 123
+#define RSA_F_RSA_EAY_PRIVATE_DECRYPT			 101
+#define RSA_F_RSA_EAY_PRIVATE_ENCRYPT			 102
+#define RSA_F_RSA_EAY_PUBLIC_DECRYPT			 103
+#define RSA_F_RSA_EAY_PUBLIC_ENCRYPT			 104
+#define RSA_F_RSA_GENERATE_KEY				 105
+#define RSA_F_RSA_MEMORY_LOCK				 130
+#define RSA_F_RSA_NEW_METHOD				 106
+#define RSA_F_RSA_NULL					 124
+#define RSA_F_RSA_NULL_MOD_EXP				 131
+#define RSA_F_RSA_NULL_PRIVATE_DECRYPT			 132
+#define RSA_F_RSA_NULL_PRIVATE_ENCRYPT			 133
+#define RSA_F_RSA_NULL_PUBLIC_DECRYPT			 134
+#define RSA_F_RSA_NULL_PUBLIC_ENCRYPT			 135
+#define RSA_F_RSA_PADDING_ADD_NONE			 107
+#define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP		 121
+#define RSA_F_RSA_PADDING_ADD_PKCS1_PSS			 125
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1		 108
+#define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2		 109
+#define RSA_F_RSA_PADDING_ADD_SSLV23			 110
+#define RSA_F_RSA_PADDING_ADD_X931			 127
+#define RSA_F_RSA_PADDING_CHECK_NONE			 111
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP		 122
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1		 112
+#define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2		 113
+#define RSA_F_RSA_PADDING_CHECK_SSLV23			 114
+#define RSA_F_RSA_PADDING_CHECK_X931			 128
+#define RSA_F_RSA_PRINT					 115
+#define RSA_F_RSA_PRINT_FP				 116
+#define RSA_F_RSA_SETUP_BLINDING			 136
+#define RSA_F_RSA_SIGN					 117
+#define RSA_F_RSA_SIGN_ASN1_OCTET_STRING		 118
+#define RSA_F_RSA_VERIFY				 119
+#define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING		 120
+#define RSA_F_RSA_VERIFY_PKCS1_PSS			 126
+
+/* Reason codes. */
+#define RSA_R_ALGORITHM_MISMATCH			 100
+#define RSA_R_BAD_E_VALUE				 101
+#define RSA_R_BAD_FIXED_HEADER_DECRYPT			 102
+#define RSA_R_BAD_PAD_BYTE_COUNT			 103
+#define RSA_R_BAD_SIGNATURE				 104
+#define RSA_R_BLOCK_TYPE_IS_NOT_01			 106
+#define RSA_R_BLOCK_TYPE_IS_NOT_02			 107
+#define RSA_R_DATA_GREATER_THAN_MOD_LEN			 108
+#define RSA_R_DATA_TOO_LARGE				 109
+#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE		 110
+#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS		 132
+#define RSA_R_DATA_TOO_SMALL				 111
+#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE		 122
+#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY		 112
+#define RSA_R_DMP1_NOT_CONGRUENT_TO_D			 124
+#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D			 125
+#define RSA_R_D_E_NOT_CONGRUENT_TO_1			 123
+#define RSA_R_FIRST_OCTET_INVALID			 133
+#define RSA_R_INVALID_HEADER				 137
+#define RSA_R_INVALID_MESSAGE_LENGTH			 131
+#define RSA_R_INVALID_PADDING				 138
+#define RSA_R_INVALID_TRAILER				 139
+#define RSA_R_IQMP_NOT_INVERSE_OF_Q			 126
+#define RSA_R_KEY_SIZE_TOO_SMALL			 120
+#define RSA_R_LAST_OCTET_INVALID			 134
+#define RSA_R_NO_PUBLIC_EXPONENT			 140
+#define RSA_R_NULL_BEFORE_BLOCK_MISSING			 113
+#define RSA_R_N_DOES_NOT_EQUAL_P_Q			 127
+#define RSA_R_OAEP_DECODING_ERROR			 121
+#define RSA_R_SLEN_RECOVERY_FAILED			 135
+#define RSA_R_PADDING_CHECK_FAILED			 114
+#define RSA_R_P_NOT_PRIME				 128
+#define RSA_R_Q_NOT_PRIME				 129
+#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED		 130
+#define RSA_R_SSLV3_ROLLBACK_ATTACK			 115
+#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116
+#define RSA_R_UNKNOWN_ALGORITHM_TYPE			 117
+#define RSA_R_UNKNOWN_PADDING_TYPE			 118
+#define RSA_R_WRONG_SIGNATURE_LENGTH			 119
+#define RSA_R_SLEN_CHECK_FAILED				 136
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/safestack.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/safestack.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/safestack.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,1784 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SAFESTACK_H
+#define HEADER_SAFESTACK_H
+
+#include <openssl/stack.h>
+
+typedef void (*openssl_fptr)(void);
+#define openssl_fcast(f) ((openssl_fptr)f)
+
+#ifdef DEBUG_SAFESTACK
+
+#define STACK_OF(type) struct stack_st_##type
+#define PREDECLARE_STACK_OF(type) STACK_OF(type);
+
+#define DECLARE_STACK_OF(type) \
+STACK_OF(type) \
+    { \
+    STACK stack; \
+    };
+
+#define IMPLEMENT_STACK_OF(type) /* nada (obsolete in new safestack approach)*/
+
+/* SKM_sk_... stack macros are internal to safestack.h:
+ * never use them directly, use sk_<type>_... instead */
+#define SKM_sk_new(type, cmp) \
+	((STACK_OF(type) * (*)(int (*)(const type * const *, const type * const *)))openssl_fcast(sk_new))(cmp)
+#define SKM_sk_new_null(type) \
+	((STACK_OF(type) * (*)(void))openssl_fcast(sk_new_null))()
+#define SKM_sk_free(type, st) \
+	((void (*)(STACK_OF(type) *))openssl_fcast(sk_free))(st)
+#define SKM_sk_num(type, st) \
+	((int (*)(const STACK_OF(type) *))openssl_fcast(sk_num))(st)
+#define SKM_sk_value(type, st,i) \
+	((type * (*)(const STACK_OF(type) *, int))openssl_fcast(sk_value))(st, i)
+#define SKM_sk_set(type, st,i,val) \
+	((type * (*)(STACK_OF(type) *, int, type *))openssl_fcast(sk_set))(st, i, val)
+#define SKM_sk_zero(type, st) \
+	((void (*)(STACK_OF(type) *))openssl_fcast(sk_zero))(st)
+#define SKM_sk_push(type, st,val) \
+	((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_push))(st, val)
+#define SKM_sk_unshift(type, st,val) \
+	((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_unshift))(st, val)
+#define SKM_sk_find(type, st,val) \
+	((int (*)(STACK_OF(type) *, type *))openssl_fcast(sk_find))(st, val)
+#define SKM_sk_delete(type, st,i) \
+	((type * (*)(STACK_OF(type) *, int))openssl_fcast(sk_delete))(st, i)
+#define SKM_sk_delete_ptr(type, st,ptr) \
+	((type * (*)(STACK_OF(type) *, type *))openssl_fcast(sk_delete_ptr))(st, ptr)
+#define SKM_sk_insert(type, st,val,i) \
+	((int (*)(STACK_OF(type) *, type *, int))openssl_fcast(sk_insert))(st, val, i)
+#define SKM_sk_set_cmp_func(type, st,cmp) \
+	((int (*(*)(STACK_OF(type) *, int (*)(const type * const *, const type * const *))) \
+	  (const type * const *, const type * const *))openssl_fcast(sk_set_cmp_func))\
+	(st, cmp)
+#define SKM_sk_dup(type, st) \
+	((STACK_OF(type) *(*)(STACK_OF(type) *))openssl_fcast(sk_dup))(st)
+#define SKM_sk_pop_free(type, st,free_func) \
+	((void (*)(STACK_OF(type) *, void (*)(type *)))openssl_fcast(sk_pop_free))\
+	(st, free_func)
+#define SKM_sk_shift(type, st) \
+	((type * (*)(STACK_OF(type) *))openssl_fcast(sk_shift))(st)
+#define SKM_sk_pop(type, st) \
+	((type * (*)(STACK_OF(type) *))openssl_fcast(sk_pop))(st)
+#define SKM_sk_sort(type, st) \
+	((void (*)(STACK_OF(type) *))openssl_fcast(sk_sort))(st)
+#define SKM_sk_is_sorted(type, st) \
+	((int (*)(const STACK_OF(type) *))openssl_fcast(sk_is_sorted))(st)
+
+#define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+((STACK_OF(type) * (*) (STACK_OF(type) **,const unsigned char **, long , \
+                         type *(*)(type **, const unsigned char **,long), \
+                                void (*)(type *), int ,int )) openssl_fcast(d2i_ASN1_SET)) \
+			(st,pp,length, d2i_func, free_func, ex_tag,ex_class)
+#define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	((int (*)(STACK_OF(type) *,unsigned char **, \
+        int (*)(type *,unsigned char **), int , int , int)) openssl_fcast(i2d_ASN1_SET)) \
+						(st,pp,i2d_func,ex_tag,ex_class,is_set)
+
+#define	SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
+	((unsigned char *(*)(STACK_OF(type) *, \
+        int (*)(type *,unsigned char **), unsigned char **,int *)) openssl_fcast(ASN1_seq_pack)) \
+				(st, i2d_func, buf, len)
+#define	SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
+	((STACK_OF(type) * (*)(const unsigned char *,int, \
+                              type *(*)(type **,const unsigned char **, long), \
+                              void (*)(type *)))openssl_fcast(ASN1_seq_unpack)) \
+					(buf,len,d2i_func, free_func)
+
+#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	((STACK_OF(type) * (*)(X509_ALGOR *, \
+            		type *(*)(type **, const unsigned char **, long), \
+				void (*)(type *), \
+                                const char *, int, \
+                                ASN1_STRING *, int))PKCS12_decrypt_d2i) \
+				(algor,d2i_func,free_func,pass,passlen,oct,seq)
+
+#else
+
+#define STACK_OF(type) STACK
+#define PREDECLARE_STACK_OF(type) /* nada */
+#define DECLARE_STACK_OF(type)    /* nada */
+#define IMPLEMENT_STACK_OF(type)  /* nada */
+
+#define SKM_sk_new(type, cmp) \
+	sk_new((int (*)(const char * const *, const char * const *))(cmp))
+#define SKM_sk_new_null(type) \
+	sk_new_null()
+#define SKM_sk_free(type, st) \
+	sk_free(st)
+#define SKM_sk_num(type, st) \
+	sk_num(st)
+#define SKM_sk_value(type, st,i) \
+	((type *)sk_value(st, i))
+#define SKM_sk_set(type, st,i,val) \
+	((type *)sk_set(st, i,(char *)val))
+#define SKM_sk_zero(type, st) \
+	sk_zero(st)
+#define SKM_sk_push(type, st,val) \
+	sk_push(st, (char *)val)
+#define SKM_sk_unshift(type, st,val) \
+	sk_unshift(st, val)
+#define SKM_sk_find(type, st,val) \
+	sk_find(st, (char *)val)
+#define SKM_sk_delete(type, st,i) \
+	((type *)sk_delete(st, i))
+#define SKM_sk_delete_ptr(type, st,ptr) \
+	((type *)sk_delete_ptr(st,(char *)ptr))
+#define SKM_sk_insert(type, st,val,i) \
+	sk_insert(st, (char *)val, i)
+#define SKM_sk_set_cmp_func(type, st,cmp) \
+	((int (*)(const type * const *,const type * const *)) \
+	sk_set_cmp_func(st, (int (*)(const char * const *, const char * const *))(cmp)))
+#define SKM_sk_dup(type, st) \
+	sk_dup(st)
+#define SKM_sk_pop_free(type, st,free_func) \
+	sk_pop_free(st, (void (*)(void *))free_func)
+#define SKM_sk_shift(type, st) \
+	((type *)sk_shift(st))
+#define SKM_sk_pop(type, st) \
+	((type *)sk_pop(st))
+#define SKM_sk_sort(type, st) \
+	sk_sort(st)
+#define SKM_sk_is_sorted(type, st) \
+	sk_is_sorted(st)
+
+#define	SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	d2i_ASN1_SET(st,pp,length, (void *(*)(void ** ,const unsigned char ** ,long))d2i_func, (void (*)(void *))free_func, ex_tag,ex_class)
+#define	SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	i2d_ASN1_SET(st,pp,(int (*)(void *, unsigned char **))i2d_func,ex_tag,ex_class,is_set)
+
+#define	SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \
+	ASN1_seq_pack(st, (int (*)(void *, unsigned char **))i2d_func, buf, len)
+#define	SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \
+	ASN1_seq_unpack(buf,len,(void *(*)(void **,const unsigned char **,long))d2i_func, (void(*)(void *))free_func)
+
+#define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	((STACK *)PKCS12_decrypt_d2i(algor,(char *(*)())d2i_func, (void(*)(void *))free_func,pass,passlen,oct,seq))
+
+#endif
+
+/* This block of defines is updated by util/mkstack.pl, please do not touch! */
+#define sk_ACCESS_DESCRIPTION_new(st) SKM_sk_new(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION)
+#define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i))
+#define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val))
+#define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val))
+#define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i))
+#define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr))
+#define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i))
+#define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp))
+#define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st)
+#define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func))
+#define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st))
+#define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st))
+
+#define sk_ASN1_GENERALSTRING_new(st) SKM_sk_new(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING)
+#define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i))
+#define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val))
+#define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val))
+#define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i))
+#define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr))
+#define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i))
+#define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp))
+#define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st)
+#define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func))
+#define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st))
+#define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st))
+
+#define sk_ASN1_INTEGER_new(st) SKM_sk_new(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER)
+#define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i))
+#define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val))
+#define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val))
+#define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i))
+#define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr))
+#define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i))
+#define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp))
+#define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st)
+#define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func))
+#define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st))
+#define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st))
+
+#define sk_ASN1_OBJECT_new(st) SKM_sk_new(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT)
+#define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i))
+#define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val))
+#define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val))
+#define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i))
+#define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr))
+#define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i))
+#define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp))
+#define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st)
+#define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func))
+#define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st))
+#define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st))
+
+#define sk_ASN1_STRING_TABLE_new(st) SKM_sk_new(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE)
+#define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i))
+#define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val))
+#define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val))
+#define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i))
+#define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr))
+#define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i))
+#define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp))
+#define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st)
+#define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func))
+#define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st))
+#define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st))
+
+#define sk_ASN1_TYPE_new(st) SKM_sk_new(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE)
+#define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i))
+#define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val))
+#define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val))
+#define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i))
+#define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr))
+#define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i))
+#define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp))
+#define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st)
+#define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func))
+#define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st))
+#define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st))
+
+#define sk_ASN1_VALUE_new(st) SKM_sk_new(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE)
+#define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i))
+#define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val))
+#define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val))
+#define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i))
+#define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr))
+#define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i))
+#define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp))
+#define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st)
+#define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func))
+#define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st))
+#define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st))
+
+#define sk_BIO_new(st) SKM_sk_new(BIO, (st))
+#define sk_BIO_new_null() SKM_sk_new_null(BIO)
+#define sk_BIO_free(st) SKM_sk_free(BIO, (st))
+#define sk_BIO_num(st) SKM_sk_num(BIO, (st))
+#define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i))
+#define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val))
+#define sk_BIO_zero(st) SKM_sk_zero(BIO, (st))
+#define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val))
+#define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val))
+#define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val))
+#define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val))
+#define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i))
+#define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr))
+#define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i))
+#define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp))
+#define sk_BIO_dup(st) SKM_sk_dup(BIO, st)
+#define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func))
+#define sk_BIO_shift(st) SKM_sk_shift(BIO, (st))
+#define sk_BIO_pop(st) SKM_sk_pop(BIO, (st))
+#define sk_BIO_sort(st) SKM_sk_sort(BIO, (st))
+#define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st))
+
+#define sk_CONF_IMODULE_new(st) SKM_sk_new(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE)
+#define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i))
+#define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val))
+#define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val))
+#define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i))
+#define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr))
+#define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i))
+#define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp))
+#define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st)
+#define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func))
+#define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st))
+#define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st))
+
+#define sk_CONF_MODULE_new(st) SKM_sk_new(CONF_MODULE, (st))
+#define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE)
+#define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st))
+#define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st))
+#define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i))
+#define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val))
+#define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st))
+#define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val))
+#define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i))
+#define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr))
+#define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i))
+#define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp))
+#define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st)
+#define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func))
+#define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st))
+#define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st))
+#define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st))
+#define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st))
+
+#define sk_CONF_VALUE_new(st) SKM_sk_new(CONF_VALUE, (st))
+#define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE)
+#define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st))
+#define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st))
+#define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i))
+#define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val))
+#define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st))
+#define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val))
+#define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i))
+#define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr))
+#define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i))
+#define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp))
+#define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st)
+#define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func))
+#define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st))
+#define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st))
+#define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st))
+#define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st))
+
+#define sk_CRYPTO_EX_DATA_FUNCS_new(st) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS)
+#define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val))
+#define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr))
+#define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i))
+#define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp))
+#define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st)
+#define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func))
+#define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st))
+#define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st))
+
+#define sk_CRYPTO_dynlock_new(st) SKM_sk_new(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock)
+#define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i))
+#define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val))
+#define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val))
+#define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i))
+#define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr))
+#define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i))
+#define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp))
+#define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st)
+#define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func))
+#define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st))
+#define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st))
+
+#define sk_DIST_POINT_new(st) SKM_sk_new(DIST_POINT, (st))
+#define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT)
+#define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st))
+#define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st))
+#define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i))
+#define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val))
+#define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st))
+#define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val))
+#define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i))
+#define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr))
+#define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i))
+#define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp))
+#define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st)
+#define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func))
+#define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st))
+#define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st))
+#define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st))
+#define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st))
+
+#define sk_ENGINE_new(st) SKM_sk_new(ENGINE, (st))
+#define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE)
+#define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st))
+#define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st))
+#define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i))
+#define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val))
+#define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st))
+#define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val))
+#define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val))
+#define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val))
+#define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val))
+#define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i))
+#define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr))
+#define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i))
+#define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp))
+#define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st)
+#define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func))
+#define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st))
+#define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st))
+#define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st))
+#define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st))
+
+#define sk_ENGINE_CLEANUP_ITEM_new(st) SKM_sk_new(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM)
+#define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i))
+#define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val))
+#define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val))
+#define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i))
+#define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr))
+#define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i))
+#define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp))
+#define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st)
+#define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func))
+#define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st))
+#define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st))
+
+#define sk_GENERAL_NAME_new(st) SKM_sk_new(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME)
+#define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i))
+#define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val))
+#define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val))
+#define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i))
+#define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr))
+#define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i))
+#define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp))
+#define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st)
+#define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func))
+#define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st))
+#define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st))
+
+#define sk_GENERAL_SUBTREE_new(st) SKM_sk_new(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE)
+#define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i))
+#define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val))
+#define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val))
+#define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i))
+#define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr))
+#define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i))
+#define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp))
+#define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st)
+#define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func))
+#define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st))
+#define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st))
+
+#define sk_KRB5_APREQBODY_new(st) SKM_sk_new(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY)
+#define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i))
+#define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val))
+#define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val))
+#define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i))
+#define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr))
+#define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i))
+#define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp))
+#define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st)
+#define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func))
+#define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st))
+#define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st))
+
+#define sk_KRB5_AUTHDATA_new(st) SKM_sk_new(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA)
+#define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i))
+#define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val))
+#define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val))
+#define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i))
+#define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr))
+#define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i))
+#define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp))
+#define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st)
+#define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func))
+#define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st))
+#define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st))
+
+#define sk_KRB5_AUTHENTBODY_new(st) SKM_sk_new(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY)
+#define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i))
+#define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val))
+#define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val))
+#define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i))
+#define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr))
+#define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i))
+#define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp))
+#define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st)
+#define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func))
+#define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st))
+#define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st))
+
+#define sk_KRB5_CHECKSUM_new(st) SKM_sk_new(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM)
+#define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i))
+#define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val))
+#define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val))
+#define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i))
+#define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr))
+#define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i))
+#define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp))
+#define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st)
+#define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func))
+#define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st))
+#define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st))
+
+#define sk_KRB5_ENCDATA_new(st) SKM_sk_new(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA)
+#define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i))
+#define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val))
+#define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val))
+#define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i))
+#define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr))
+#define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i))
+#define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp))
+#define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st)
+#define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func))
+#define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st))
+#define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st))
+
+#define sk_KRB5_ENCKEY_new(st) SKM_sk_new(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY)
+#define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i))
+#define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val))
+#define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val))
+#define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i))
+#define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr))
+#define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i))
+#define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp))
+#define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st)
+#define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func))
+#define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st))
+#define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st))
+
+#define sk_KRB5_PRINCNAME_new(st) SKM_sk_new(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME)
+#define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i))
+#define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val))
+#define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val))
+#define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i))
+#define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr))
+#define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i))
+#define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp))
+#define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st)
+#define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func))
+#define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st))
+#define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st))
+
+#define sk_KRB5_TKTBODY_new(st) SKM_sk_new(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY)
+#define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i))
+#define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val))
+#define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val))
+#define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i))
+#define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr))
+#define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i))
+#define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp))
+#define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st)
+#define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func))
+#define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st))
+#define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st))
+
+#define sk_MIME_HEADER_new(st) SKM_sk_new(MIME_HEADER, (st))
+#define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER)
+#define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st))
+#define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st))
+#define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val))
+#define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st))
+#define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val))
+#define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i))
+#define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr))
+#define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i))
+#define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp))
+#define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st)
+#define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func))
+#define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st))
+#define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st))
+#define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st))
+#define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st))
+
+#define sk_MIME_PARAM_new(st) SKM_sk_new(MIME_PARAM, (st))
+#define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM)
+#define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st))
+#define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st))
+#define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val))
+#define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st))
+#define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val))
+#define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i))
+#define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr))
+#define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i))
+#define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp))
+#define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st)
+#define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func))
+#define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st))
+#define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st))
+#define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st))
+#define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st))
+
+#define sk_NAME_FUNCS_new(st) SKM_sk_new(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS)
+#define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i))
+#define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val))
+#define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val))
+#define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i))
+#define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr))
+#define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i))
+#define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp))
+#define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st)
+#define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func))
+#define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st))
+#define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st))
+
+#define sk_OCSP_CERTID_new(st) SKM_sk_new(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID)
+#define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i))
+#define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val))
+#define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val))
+#define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i))
+#define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr))
+#define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i))
+#define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp))
+#define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st)
+#define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func))
+#define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st))
+#define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st))
+
+#define sk_OCSP_ONEREQ_new(st) SKM_sk_new(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ)
+#define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i))
+#define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val))
+#define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val))
+#define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i))
+#define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr))
+#define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i))
+#define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp))
+#define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st)
+#define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func))
+#define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st))
+#define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st))
+
+#define sk_OCSP_SINGLERESP_new(st) SKM_sk_new(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP)
+#define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i))
+#define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val))
+#define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val))
+#define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i))
+#define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr))
+#define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i))
+#define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp))
+#define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st)
+#define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func))
+#define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st))
+#define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st))
+
+#define sk_PKCS12_SAFEBAG_new(st) SKM_sk_new(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG)
+#define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i))
+#define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val))
+#define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val))
+#define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i))
+#define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr))
+#define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i))
+#define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp))
+#define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st)
+#define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func))
+#define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st))
+#define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st))
+
+#define sk_PKCS7_new(st) SKM_sk_new(PKCS7, (st))
+#define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7)
+#define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st))
+#define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st))
+#define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i))
+#define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val))
+#define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st))
+#define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val))
+#define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val))
+#define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val))
+#define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val))
+#define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i))
+#define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr))
+#define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i))
+#define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp))
+#define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st)
+#define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func))
+#define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st))
+#define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st))
+#define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st))
+#define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st))
+
+#define sk_PKCS7_RECIP_INFO_new(st) SKM_sk_new(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO)
+#define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i))
+#define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val))
+#define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val))
+#define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i))
+#define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr))
+#define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i))
+#define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp))
+#define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st)
+#define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func))
+#define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st))
+#define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st))
+
+#define sk_PKCS7_SIGNER_INFO_new(st) SKM_sk_new(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO)
+#define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i))
+#define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val))
+#define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val))
+#define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i))
+#define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr))
+#define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i))
+#define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp))
+#define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st)
+#define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func))
+#define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st))
+#define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st))
+
+#define sk_POLICYINFO_new(st) SKM_sk_new(POLICYINFO, (st))
+#define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO)
+#define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st))
+#define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st))
+#define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i))
+#define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val))
+#define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st))
+#define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val))
+#define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i))
+#define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr))
+#define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i))
+#define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp))
+#define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st)
+#define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func))
+#define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st))
+#define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st))
+#define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st))
+#define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st))
+
+#define sk_POLICYQUALINFO_new(st) SKM_sk_new(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO)
+#define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i))
+#define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val))
+#define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val))
+#define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i))
+#define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr))
+#define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i))
+#define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp))
+#define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st)
+#define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func))
+#define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st))
+#define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st))
+
+#define sk_POLICY_MAPPING_new(st) SKM_sk_new(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING)
+#define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i))
+#define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val))
+#define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val))
+#define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i))
+#define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr))
+#define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i))
+#define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp))
+#define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st)
+#define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func))
+#define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st))
+#define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st))
+
+#define sk_SSL_CIPHER_new(st) SKM_sk_new(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER)
+#define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i))
+#define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val))
+#define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val))
+#define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i))
+#define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr))
+#define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i))
+#define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp))
+#define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st)
+#define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func))
+#define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st))
+#define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st))
+
+#define sk_SSL_COMP_new(st) SKM_sk_new(SSL_COMP, (st))
+#define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP)
+#define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st))
+#define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st))
+#define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i))
+#define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val))
+#define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st))
+#define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val))
+#define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i))
+#define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr))
+#define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i))
+#define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp))
+#define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st)
+#define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func))
+#define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st))
+#define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st))
+#define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st))
+#define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st))
+
+#define sk_STORE_OBJECT_new(st) SKM_sk_new(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT)
+#define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i))
+#define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val))
+#define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val))
+#define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i))
+#define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr))
+#define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i))
+#define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp))
+#define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st)
+#define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func))
+#define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st))
+#define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st))
+
+#define sk_SXNETID_new(st) SKM_sk_new(SXNETID, (st))
+#define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID)
+#define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st))
+#define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st))
+#define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i))
+#define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val))
+#define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st))
+#define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val))
+#define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val))
+#define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val))
+#define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val))
+#define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i))
+#define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr))
+#define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i))
+#define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp))
+#define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st)
+#define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func))
+#define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st))
+#define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st))
+#define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st))
+#define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st))
+
+#define sk_UI_STRING_new(st) SKM_sk_new(UI_STRING, (st))
+#define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING)
+#define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st))
+#define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st))
+#define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i))
+#define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val))
+#define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st))
+#define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val))
+#define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val))
+#define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val))
+#define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val))
+#define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i))
+#define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr))
+#define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i))
+#define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp))
+#define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st)
+#define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func))
+#define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st))
+#define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st))
+#define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st))
+#define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st))
+
+#define sk_X509_new(st) SKM_sk_new(X509, (st))
+#define sk_X509_new_null() SKM_sk_new_null(X509)
+#define sk_X509_free(st) SKM_sk_free(X509, (st))
+#define sk_X509_num(st) SKM_sk_num(X509, (st))
+#define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i))
+#define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val))
+#define sk_X509_zero(st) SKM_sk_zero(X509, (st))
+#define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val))
+#define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val))
+#define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val))
+#define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val))
+#define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i))
+#define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr))
+#define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i))
+#define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp))
+#define sk_X509_dup(st) SKM_sk_dup(X509, st)
+#define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func))
+#define sk_X509_shift(st) SKM_sk_shift(X509, (st))
+#define sk_X509_pop(st) SKM_sk_pop(X509, (st))
+#define sk_X509_sort(st) SKM_sk_sort(X509, (st))
+#define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st))
+
+#define sk_X509V3_EXT_METHOD_new(st) SKM_sk_new(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD)
+#define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i))
+#define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val))
+#define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val))
+#define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i))
+#define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr))
+#define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i))
+#define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp))
+#define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st)
+#define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func))
+#define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st))
+#define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st))
+
+#define sk_X509_ALGOR_new(st) SKM_sk_new(X509_ALGOR, (st))
+#define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR)
+#define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st))
+#define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st))
+#define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i))
+#define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val))
+#define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st))
+#define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val))
+#define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i))
+#define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr))
+#define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i))
+#define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp))
+#define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st)
+#define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func))
+#define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st))
+#define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st))
+#define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st))
+#define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st))
+
+#define sk_X509_ATTRIBUTE_new(st) SKM_sk_new(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE)
+#define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i))
+#define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val))
+#define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val))
+#define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i))
+#define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr))
+#define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i))
+#define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp))
+#define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st)
+#define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func))
+#define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st))
+#define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st))
+
+#define sk_X509_CRL_new(st) SKM_sk_new(X509_CRL, (st))
+#define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL)
+#define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st))
+#define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st))
+#define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i))
+#define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val))
+#define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st))
+#define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val))
+#define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val))
+#define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val))
+#define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val))
+#define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i))
+#define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr))
+#define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i))
+#define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp))
+#define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st)
+#define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func))
+#define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st))
+#define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st))
+#define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st))
+#define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st))
+
+#define sk_X509_EXTENSION_new(st) SKM_sk_new(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION)
+#define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i))
+#define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val))
+#define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val))
+#define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i))
+#define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr))
+#define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i))
+#define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp))
+#define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st)
+#define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func))
+#define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st))
+#define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st))
+
+#define sk_X509_INFO_new(st) SKM_sk_new(X509_INFO, (st))
+#define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO)
+#define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st))
+#define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st))
+#define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i))
+#define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val))
+#define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st))
+#define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val))
+#define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val))
+#define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val))
+#define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val))
+#define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i))
+#define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr))
+#define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i))
+#define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp))
+#define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st)
+#define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func))
+#define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st))
+#define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st))
+#define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st))
+#define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st))
+
+#define sk_X509_LOOKUP_new(st) SKM_sk_new(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP)
+#define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i))
+#define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val))
+#define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val))
+#define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i))
+#define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr))
+#define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i))
+#define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp))
+#define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st)
+#define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func))
+#define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st))
+#define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st))
+
+#define sk_X509_NAME_new(st) SKM_sk_new(X509_NAME, (st))
+#define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME)
+#define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st))
+#define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st))
+#define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i))
+#define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val))
+#define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st))
+#define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val))
+#define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val))
+#define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val))
+#define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val))
+#define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i))
+#define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr))
+#define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i))
+#define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp))
+#define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st)
+#define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func))
+#define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st))
+#define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st))
+#define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st))
+#define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st))
+
+#define sk_X509_NAME_ENTRY_new(st) SKM_sk_new(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY)
+#define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i))
+#define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val))
+#define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val))
+#define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i))
+#define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr))
+#define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i))
+#define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp))
+#define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st)
+#define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func))
+#define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st))
+#define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st))
+
+#define sk_X509_OBJECT_new(st) SKM_sk_new(X509_OBJECT, (st))
+#define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT)
+#define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st))
+#define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st))
+#define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i))
+#define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val))
+#define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st))
+#define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val))
+#define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i))
+#define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr))
+#define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i))
+#define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp))
+#define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st)
+#define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func))
+#define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st))
+#define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st))
+#define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st))
+#define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st))
+
+#define sk_X509_POLICY_DATA_new(st) SKM_sk_new(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA)
+#define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i))
+#define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val))
+#define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val))
+#define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i))
+#define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr))
+#define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i))
+#define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp))
+#define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st)
+#define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func))
+#define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st))
+#define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st))
+
+#define sk_X509_POLICY_NODE_new(st) SKM_sk_new(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE)
+#define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i))
+#define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val))
+#define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val))
+#define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i))
+#define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr))
+#define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i))
+#define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp))
+#define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st)
+#define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func))
+#define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st))
+#define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st))
+
+#define sk_X509_POLICY_REF_new(st) SKM_sk_new(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_new_null() SKM_sk_new_null(X509_POLICY_REF)
+#define sk_X509_POLICY_REF_free(st) SKM_sk_free(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_num(st) SKM_sk_num(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_value(st, i) SKM_sk_value(X509_POLICY_REF, (st), (i))
+#define sk_X509_POLICY_REF_set(st, i, val) SKM_sk_set(X509_POLICY_REF, (st), (i), (val))
+#define sk_X509_POLICY_REF_zero(st) SKM_sk_zero(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_push(st, val) SKM_sk_push(X509_POLICY_REF, (st), (val))
+#define sk_X509_POLICY_REF_unshift(st, val) SKM_sk_unshift(X509_POLICY_REF, (st), (val))
+#define sk_X509_POLICY_REF_find(st, val) SKM_sk_find(X509_POLICY_REF, (st), (val))
+#define sk_X509_POLICY_REF_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_REF, (st), (val))
+#define sk_X509_POLICY_REF_delete(st, i) SKM_sk_delete(X509_POLICY_REF, (st), (i))
+#define sk_X509_POLICY_REF_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_REF, (st), (ptr))
+#define sk_X509_POLICY_REF_insert(st, val, i) SKM_sk_insert(X509_POLICY_REF, (st), (val), (i))
+#define sk_X509_POLICY_REF_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_REF, (st), (cmp))
+#define sk_X509_POLICY_REF_dup(st) SKM_sk_dup(X509_POLICY_REF, st)
+#define sk_X509_POLICY_REF_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_REF, (st), (free_func))
+#define sk_X509_POLICY_REF_shift(st) SKM_sk_shift(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_pop(st) SKM_sk_pop(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_sort(st) SKM_sk_sort(X509_POLICY_REF, (st))
+#define sk_X509_POLICY_REF_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_REF, (st))
+
+#define sk_X509_PURPOSE_new(st) SKM_sk_new(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE)
+#define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i))
+#define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val))
+#define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val))
+#define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i))
+#define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr))
+#define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i))
+#define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp))
+#define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st)
+#define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func))
+#define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st))
+#define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st))
+
+#define sk_X509_REVOKED_new(st) SKM_sk_new(X509_REVOKED, (st))
+#define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED)
+#define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st))
+#define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st))
+#define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i))
+#define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val))
+#define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st))
+#define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val))
+#define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i))
+#define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr))
+#define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i))
+#define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp))
+#define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st)
+#define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func))
+#define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st))
+#define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st))
+#define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st))
+#define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st))
+
+#define sk_X509_TRUST_new(st) SKM_sk_new(X509_TRUST, (st))
+#define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST)
+#define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st))
+#define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st))
+#define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i))
+#define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val))
+#define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st))
+#define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val))
+#define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i))
+#define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr))
+#define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i))
+#define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp))
+#define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st)
+#define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func))
+#define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st))
+#define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st))
+#define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st))
+#define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st))
+
+#define sk_X509_VERIFY_PARAM_new(st) SKM_sk_new(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM)
+#define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i))
+#define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val))
+#define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val))
+#define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i))
+#define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr))
+#define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i))
+#define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp))
+#define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st)
+#define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func))
+#define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st))
+#define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st))
+
+#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func))
+
+#define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
+	SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+#define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \
+	SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
+#define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \
+	SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len))
+#define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \
+	SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func))
+
+#define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+
+#define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \
+	SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq))
+/* End of util/mkstack.pl block, you may now edit :-) */
+
+#endif /* !defined HEADER_SAFESTACK_H */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/sha.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/sha.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/sha.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,199 @@
+/* crypto/sha/sha.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SHA_H
+#define HEADER_SHA_H
+
+#include <openssl/e_os2.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1))
+#error SHA is disabled.
+#endif
+
+#if defined(OPENSSL_FIPS)
+#define FIPS_SHA_SIZE_T size_t
+#endif
+
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
+ * ! SHA_LONG_LOG2 has to be defined along.                        !
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
+#if defined(OPENSSL_SYS_WIN16) || defined(__LP32__)
+#define SHA_LONG unsigned long
+#elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__)
+#define SHA_LONG unsigned long
+#define SHA_LONG_LOG2 3
+#else
+#define SHA_LONG unsigned int
+#endif
+
+#define SHA_LBLOCK	16
+#define SHA_CBLOCK	(SHA_LBLOCK*4)	/* SHA treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA_LAST_BLOCK  (SHA_CBLOCK-8)
+#define SHA_DIGEST_LENGTH 20
+
+typedef struct SHAstate_st
+	{
+	SHA_LONG h0,h1,h2,h3,h4;
+	SHA_LONG Nl,Nh;
+	SHA_LONG data[SHA_LBLOCK];
+	unsigned int num;
+	} SHA_CTX;
+
+#ifndef OPENSSL_NO_SHA0
+int SHA_Init(SHA_CTX *c);
+int SHA_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md);
+void SHA_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+#ifndef OPENSSL_NO_SHA1
+int SHA1_Init(SHA_CTX *c);
+int SHA1_Update(SHA_CTX *c, const void *data, size_t len);
+int SHA1_Final(unsigned char *md, SHA_CTX *c);
+unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md);
+void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
+#endif
+
+#define SHA256_CBLOCK	(SHA_LBLOCK*4)	/* SHA-256 treats input data as a
+					 * contiguous array of 32 bit
+					 * wide big-endian values. */
+#define SHA224_DIGEST_LENGTH	28
+#define SHA256_DIGEST_LENGTH	32
+
+typedef struct SHA256state_st
+	{
+	SHA_LONG h[8];
+	SHA_LONG Nl,Nh;
+	SHA_LONG data[SHA_LBLOCK];
+	unsigned int num,md_len;
+	} SHA256_CTX;
+
+#ifndef OPENSSL_NO_SHA256
+int SHA224_Init(SHA256_CTX *c);
+int SHA224_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA224_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA224(const unsigned char *d, size_t n,unsigned char *md);
+int SHA256_Init(SHA256_CTX *c);
+int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
+int SHA256_Final(unsigned char *md, SHA256_CTX *c);
+unsigned char *SHA256(const unsigned char *d, size_t n,unsigned char *md);
+void SHA256_Transform(SHA256_CTX *c, const unsigned char *data);
+#endif
+
+#define SHA384_DIGEST_LENGTH	48
+#define SHA512_DIGEST_LENGTH	64
+
+#ifndef OPENSSL_NO_SHA512
+/*
+ * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64
+ * being exactly 64-bit wide. See Implementation Notes in sha512.c
+ * for further details.
+ */
+#define SHA512_CBLOCK	(SHA_LBLOCK*8)	/* SHA-512 treats input data as a
+					 * contiguous array of 64 bit
+					 * wide big-endian values. */
+#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
+#define SHA_LONG64 unsigned __int64
+#define U64(C)     C##UI64
+#elif defined(__arch64__)
+#define SHA_LONG64 unsigned long
+#define U64(C)     C##UL
+#else
+#define SHA_LONG64 unsigned long long
+#define U64(C)     C##ULL
+#endif
+
+typedef struct SHA512state_st
+	{
+	SHA_LONG64 h[8];
+	SHA_LONG64 Nl,Nh;
+	union {
+		SHA_LONG64	d[SHA_LBLOCK];
+		unsigned char	p[SHA512_CBLOCK];
+	} u;
+	unsigned int num,md_len;
+	} SHA512_CTX;
+#endif
+
+#ifndef OPENSSL_NO_SHA512
+int SHA384_Init(SHA512_CTX *c);
+int SHA384_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA384_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA384(const unsigned char *d, size_t n,unsigned char *md);
+int SHA512_Init(SHA512_CTX *c);
+int SHA512_Update(SHA512_CTX *c, const void *data, size_t len);
+int SHA512_Final(unsigned char *md, SHA512_CTX *c);
+unsigned char *SHA512(const unsigned char *d, size_t n,unsigned char *md);
+void SHA512_Transform(SHA512_CTX *c, const unsigned char *data);
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,1961 @@
+/* ssl/ssl.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_SSL_H 
+#define HEADER_SSL_H 
+
+#include <openssl/e_os2.h>
+
+#ifndef OPENSSL_NO_COMP
+#include <openssl/comp.h>
+#endif
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#ifndef OPENSSL_NO_DEPRECATED
+#ifndef OPENSSL_NO_X509
+#include <openssl/x509.h>
+#endif
+#include <openssl/crypto.h>
+#include <openssl/lhash.h>
+#include <openssl/buffer.h>
+#endif
+#include <openssl/pem.h>
+
+#include <openssl/kssl.h>
+#include <openssl/safestack.h>
+#include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* SSLeay version number for ASN.1 encoding of the session information */
+/* Version 0 - initial version
+ * Version 1 - added the optional peer certificate
+ */
+#define SSL_SESSION_ASN1_VERSION 0x0001
+
+/* text strings for the ciphers */
+#define SSL_TXT_NULL_WITH_MD5		SSL2_TXT_NULL_WITH_MD5			
+#define SSL_TXT_RC4_128_WITH_MD5	SSL2_TXT_RC4_128_WITH_MD5		
+#define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5	
+#define SSL_TXT_RC2_128_CBC_WITH_MD5	SSL2_TXT_RC2_128_CBC_WITH_MD5		
+#define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5	
+#define SSL_TXT_IDEA_128_CBC_WITH_MD5	SSL2_TXT_IDEA_128_CBC_WITH_MD5		
+#define SSL_TXT_DES_64_CBC_WITH_MD5	SSL2_TXT_DES_64_CBC_WITH_MD5		
+#define SSL_TXT_DES_64_CBC_WITH_SHA	SSL2_TXT_DES_64_CBC_WITH_SHA		
+#define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5	
+#define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA	
+
+/*    VRS Additional Kerberos5 entries
+ */
+#define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
+#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
+#define SSL_TXT_KRB5_RC4_128_SHA      SSL3_TXT_KRB5_RC4_128_SHA
+#define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA
+#define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5       
+#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5       
+#define SSL_TXT_KRB5_RC4_128_MD5      SSL3_TXT_KRB5_RC4_128_MD5
+#define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 
+
+#define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA 
+#define SSL_TXT_KRB5_RC2_40_CBC_SHA   SSL3_TXT_KRB5_RC2_40_CBC_SHA 
+#define SSL_TXT_KRB5_RC4_40_SHA	      SSL3_TXT_KRB5_RC4_40_SHA
+#define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5 
+#define SSL_TXT_KRB5_RC2_40_CBC_MD5   SSL3_TXT_KRB5_RC2_40_CBC_MD5 
+#define SSL_TXT_KRB5_RC4_40_MD5	      SSL3_TXT_KRB5_RC4_40_MD5
+
+#define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
+#define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
+#define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
+#define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
+#define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
+#define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
+#define SSL_MAX_KRB5_PRINCIPAL_LENGTH  256
+
+#define SSL_MAX_SSL_SESSION_ID_LENGTH		32
+#define SSL_MAX_SID_CTX_LENGTH			32
+
+#define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES	(512/8)
+#define SSL_MAX_KEY_ARG_LENGTH			8
+#define SSL_MAX_MASTER_KEY_LENGTH		48
+
+/* These are used to specify which ciphers to use and not to use */
+#define SSL_TXT_LOW		"LOW"
+#define SSL_TXT_MEDIUM		"MEDIUM"
+#define SSL_TXT_HIGH		"HIGH"
+#define SSL_TXT_kFZA		"kFZA"
+#define	SSL_TXT_aFZA		"aFZA"
+#define SSL_TXT_eFZA		"eFZA"
+#define SSL_TXT_FZA		"FZA"
+
+#define	SSL_TXT_aNULL		"aNULL"
+#define	SSL_TXT_eNULL		"eNULL"
+#define	SSL_TXT_NULL		"NULL"
+
+#define SSL_TXT_kKRB5     	"kKRB5"
+#define SSL_TXT_aKRB5     	"aKRB5"
+#define SSL_TXT_KRB5      	"KRB5"
+
+#define SSL_TXT_kRSA		"kRSA"
+#define SSL_TXT_kDHr		"kDHr"
+#define SSL_TXT_kDHd		"kDHd"
+#define SSL_TXT_kEDH		"kEDH"
+#define	SSL_TXT_aRSA		"aRSA"
+#define	SSL_TXT_aDSS		"aDSS"
+#define	SSL_TXT_aDH		"aDH"
+#define	SSL_TXT_DSS		"DSS"
+#define SSL_TXT_DH		"DH"
+#define SSL_TXT_EDH		"EDH"
+#define SSL_TXT_ADH		"ADH"
+#define SSL_TXT_RSA		"RSA"
+#define SSL_TXT_DES		"DES"
+#define SSL_TXT_3DES		"3DES"
+#define SSL_TXT_RC4		"RC4"
+#define SSL_TXT_RC2		"RC2"
+#define SSL_TXT_IDEA		"IDEA"
+#define SSL_TXT_AES		"AES"
+#define SSL_TXT_MD5		"MD5"
+#define SSL_TXT_SHA1		"SHA1"
+#define SSL_TXT_SHA		"SHA"
+#define SSL_TXT_EXP		"EXP"
+#define SSL_TXT_EXPORT		"EXPORT"
+#define SSL_TXT_EXP40		"EXPORT40"
+#define SSL_TXT_EXP56		"EXPORT56"
+#define SSL_TXT_SSLV2		"SSLv2"
+#define SSL_TXT_SSLV3		"SSLv3"
+#define SSL_TXT_TLSV1		"TLSv1"
+#define SSL_TXT_ALL		"ALL"
+#define SSL_TXT_ECC		"ECCdraft" /* ECC ciphersuites are not yet official */
+
+/*
+ * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
+ * ciphers normally not being used.
+ * Example: "RC4" will activate all ciphers using RC4 including ciphers
+ * without authentication, which would normally disabled by DEFAULT (due
+ * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT"
+ * will make sure that it is also disabled in the specific selection.
+ * COMPLEMENTOF* identifiers are portable between version, as adjustments
+ * to the default cipher setup will also be included here.
+ *
+ * COMPLEMENTOFDEFAULT does not experience the same special treatment that
+ * DEFAULT gets, as only selection is being done and no sorting as needed
+ * for DEFAULT.
+ */
+#define SSL_TXT_CMPALL		"COMPLEMENTOFALL"
+#define SSL_TXT_CMPDEF		"COMPLEMENTOFDEFAULT"
+
+/* The following cipher list is used by default.
+ * It also is substituted when an application-defined cipher list string
+ * starts with 'DEFAULT'. */
+#define SSL_DEFAULT_CIPHER_LIST	"ALL:!ADH:+RC4:@STRENGTH" /* low priority for RC4 */
+
+/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
+#define SSL_SENT_SHUTDOWN	1
+#define SSL_RECEIVED_SHUTDOWN	2
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2)
+#define OPENSSL_NO_SSL2
+#endif
+
+#define SSL_FILETYPE_ASN1	X509_FILETYPE_ASN1
+#define SSL_FILETYPE_PEM	X509_FILETYPE_PEM
+
+/* This is needed to stop compilers complaining about the
+ * 'struct ssl_st *' function parameters used to prototype callbacks
+ * in SSL_CTX. */
+typedef struct ssl_st *ssl_crock_st;
+
+/* used to hold info on the particular ciphers used */
+typedef struct ssl_cipher_st
+	{
+	int valid;
+	const char *name;		/* text name */
+	unsigned long id;		/* id, 4 bytes, first is version */
+	unsigned long algorithms;	/* what ciphers are used */
+	unsigned long algo_strength;	/* strength and export flags */
+	unsigned long algorithm2;	/* Extra flags */
+	int strength_bits;		/* Number of bits really used */
+	int alg_bits;			/* Number of bits for algorithm */
+	unsigned long mask;		/* used for matching */
+	unsigned long mask_strength;	/* also used for matching */
+	} SSL_CIPHER;
+
+DECLARE_STACK_OF(SSL_CIPHER)
+
+typedef struct ssl_st SSL;
+typedef struct ssl_ctx_st SSL_CTX;
+
+/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
+typedef struct ssl_method_st
+	{
+	int version;
+	int (*ssl_new)(SSL *s);
+	void (*ssl_clear)(SSL *s);
+	void (*ssl_free)(SSL *s);
+	int (*ssl_accept)(SSL *s);
+	int (*ssl_connect)(SSL *s);
+	int (*ssl_read)(SSL *s,void *buf,int len);
+	int (*ssl_peek)(SSL *s,void *buf,int len);
+	int (*ssl_write)(SSL *s,const void *buf,int len);
+	int (*ssl_shutdown)(SSL *s);
+	int (*ssl_renegotiate)(SSL *s);
+	int (*ssl_renegotiate_check)(SSL *s);
+	long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long
+		max, int *ok);
+	int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len, 
+		int peek);
+	int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len);
+	int (*ssl_dispatch_alert)(SSL *s);
+	long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);
+	long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);
+	SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);
+	int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr);
+	int (*ssl_pending)(const SSL *s);
+	int (*num_ciphers)(void);
+	SSL_CIPHER *(*get_cipher)(unsigned ncipher);
+	struct ssl_method_st *(*get_ssl_method)(int version);
+	long (*get_timeout)(void);
+	struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
+	int (*ssl_version)(void);
+	long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));
+	long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));
+	} SSL_METHOD;
+
+/* Lets make this into an ASN.1 type structure as follows
+ * SSL_SESSION_ID ::= SEQUENCE {
+ *	version 		INTEGER,	-- structure version number
+ *	SSLversion 		INTEGER,	-- SSL version number
+ *	Cipher 			OCTET_STRING,	-- the 3 byte cipher ID
+ *	Session_ID 		OCTET_STRING,	-- the Session ID
+ *	Master_key 		OCTET_STRING,	-- the master key
+ *	KRB5_principal		OCTET_STRING	-- optional Kerberos principal
+ *	Key_Arg [ 0 ] IMPLICIT	OCTET_STRING,	-- the optional Key argument
+ *	Time [ 1 ] EXPLICIT	INTEGER,	-- optional Start Time
+ *	Timeout [ 2 ] EXPLICIT	INTEGER,	-- optional Timeout ins seconds
+ *	Peer [ 3 ] EXPLICIT	X509,		-- optional Peer Certificate
+ *	Session_ID_context [ 4 ] EXPLICIT OCTET_STRING,   -- the Session ID context
+ *	Verify_result [ 5 ] EXPLICIT INTEGER    -- X509_V_... code for `Peer'
+ *	Compression [6] IMPLICIT ASN1_OBJECT	-- compression OID XXXXX
+ *	}
+ * Look in ssl/ssl_asn1.c for more details
+ * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
+ */
+typedef struct ssl_session_st
+	{
+	int ssl_version;	/* what ssl version session info is
+				 * being kept in here? */
+
+	/* only really used in SSLv2 */
+	unsigned int key_arg_length;
+	unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH];
+	int master_key_length;
+	unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
+	/* session_id - valid? */
+	unsigned int session_id_length;
+	unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
+	/* this is used to determine whether the session is being reused in
+	 * the appropriate context. It is up to the application to set this,
+	 * via SSL_new */
+	unsigned int sid_ctx_length;
+	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+
+#ifndef OPENSSL_NO_KRB5
+        unsigned int krb5_client_princ_len;
+        unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
+#endif /* OPENSSL_NO_KRB5 */
+
+	int not_resumable;
+
+	/* The cert is the certificate used to establish this connection */
+	struct sess_cert_st /* SESS_CERT */ *sess_cert;
+
+	/* This is the cert for the other end.
+	 * On clients, it will be the same as sess_cert->peer_key->x509
+	 * (the latter is not enough as sess_cert is not retained
+	 * in the external representation of sessions, see ssl_asn1.c). */
+	X509 *peer;
+	/* when app_verify_callback accepts a session where the peer's certificate
+	 * is not ok, we must remember the error for session reuse: */
+	long verify_result; /* only for servers */
+
+	int references;
+	long timeout;
+	long time;
+
+	int compress_meth;		/* Need to lookup the method */
+
+	SSL_CIPHER *cipher;
+	unsigned long cipher_id;	/* when ASN.1 loaded, this
+					 * needs to be used to load
+					 * the 'cipher' structure */
+
+	STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
+
+	CRYPTO_EX_DATA ex_data; /* application specific data */
+
+	/* These are used to make removal of session-ids more
+	 * efficient and to implement a maximum cache size. */
+	struct ssl_session_st *prev,*next;
+	} SSL_SESSION;
+
+
+#define SSL_OP_MICROSOFT_SESS_ID_BUG			0x00000001L
+#define SSL_OP_NETSCAPE_CHALLENGE_BUG			0x00000002L
+#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG		0x00000008L
+#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG		0x00000010L
+#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER		0x00000020L
+#define SSL_OP_MSIE_SSLV2_RSA_PADDING			0x00000040L
+#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG			0x00000080L
+#define SSL_OP_TLS_D5_BUG				0x00000100L
+#define SSL_OP_TLS_BLOCK_PADDING_BUG			0x00000200L
+
+/* Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added
+ * in OpenSSL 0.9.6d.  Usually (depending on the application protocol)
+ * the workaround is not needed.  Unfortunately some broken SSL/TLS
+ * implementations cannot handle it at all, which is why we include
+ * it in SSL_OP_ALL. */
+#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L /* added in 0.9.6e */
+
+/* SSL_OP_ALL: various bug workarounds that should be rather harmless.
+ *             This used to be 0x000FFFFFL before 0.9.7. */
+#define SSL_OP_ALL					0x00000FFFL
+
+/* DTLS options */
+#define SSL_OP_NO_QUERY_MTU                 0x00001000L
+/* Turn on Cookie Exchange (on relevant for servers) */
+#define SSL_OP_COOKIE_EXCHANGE              0x00002000L
+
+/* As server, disallow session resumption on renegotiation */
+#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION	0x00010000L
+/* If set, always create a new key when using tmp_ecdh parameters */
+#define SSL_OP_SINGLE_ECDH_USE				0x00080000L
+/* If set, always create a new key when using tmp_dh parameters */
+#define SSL_OP_SINGLE_DH_USE				0x00100000L
+/* Set to always use the tmp_rsa key when doing RSA operations,
+ * even when this violates protocol specs */
+#define SSL_OP_EPHEMERAL_RSA				0x00200000L
+/* Set on servers to choose the cipher according to the server's
+ * preferences */
+#define SSL_OP_CIPHER_SERVER_PREFERENCE			0x00400000L
+/* If set, a server will allow a client to issue a SSLv3.0 version number
+ * as latest version supported in the premaster secret, even when TLSv1.0
+ * (version 3.1) was announced in the client hello. Normally this is
+ * forbidden to prevent version rollback attacks. */
+#define SSL_OP_TLS_ROLLBACK_BUG				0x00800000L
+
+#define SSL_OP_NO_SSLv2					0x01000000L
+#define SSL_OP_NO_SSLv3					0x02000000L
+#define SSL_OP_NO_TLSv1					0x04000000L
+
+/* The next flag deliberately changes the ciphertest, this is a check
+ * for the PKCS#1 attack */
+#define SSL_OP_PKCS1_CHECK_1				0x08000000L
+#define SSL_OP_PKCS1_CHECK_2				0x10000000L
+#define SSL_OP_NETSCAPE_CA_DN_BUG			0x20000000L
+#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG		0x40000000L
+
+
+/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
+ * when just a single record has been written): */
+#define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001L
+/* Make it possible to retry SSL_write() with changed buffer location
+ * (buffer contents must stay the same!); this is not the default to avoid
+ * the misconception that non-blocking SSL_write() behaves like
+ * non-blocking write(): */
+#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
+/* Never bother the application with retries if the transport
+ * is blocking: */
+#define SSL_MODE_AUTO_RETRY 0x00000004L
+/* Don't attempt to automatically build certificate chain */
+#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
+
+
+/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
+ * they cannot be used to clear bits. */
+
+#define SSL_CTX_set_options(ctx,op) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
+#define SSL_CTX_get_options(ctx) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
+#define SSL_set_options(ssl,op) \
+	SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
+#define SSL_get_options(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL)
+
+#define SSL_CTX_set_mode(ctx,op) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
+#define SSL_CTX_get_mode(ctx) \
+	SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
+#define SSL_set_mode(ssl,op) \
+	SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
+#define SSL_get_mode(ssl) \
+        SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
+#define SSL_set_mtu(ssl, mtu) \
+        SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
+
+
+void SSL_CTX_set_msg_callback(SSL_CTX *ctx, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg));
+#define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+#define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
+
+
+
+#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
+#define SSL_MAX_CERT_LIST_DEFAULT 1024*30 /* 30k max cert list :-) */
+#else
+#define SSL_MAX_CERT_LIST_DEFAULT 1024*100 /* 100k max cert list :-) */
+#endif
+
+#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT	(1024*20)
+
+/* This callback type is used inside SSL_CTX, SSL, and in the functions that set
+ * them. It is used to override the generation of SSL/TLS session IDs in a
+ * server. Return value should be zero on an error, non-zero to proceed. Also,
+ * callbacks should themselves check if the id they generate is unique otherwise
+ * the SSL handshake will fail with an error - callbacks can do this using the
+ * 'ssl' value they're passed by;
+ *      SSL_has_matching_session_id(ssl, id, *id_len)
+ * The length value passed in is set at the maximum size the session ID can be.
+ * In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback
+ * can alter this length to be less if desired, but under SSLv2 session IDs are
+ * supposed to be fixed at 16 bytes so the id will be padded after the callback
+ * returns in this case. It is also an error for the callback to set the size to
+ * zero. */
+typedef int (*GEN_SESSION_CB)(const SSL *ssl, unsigned char *id,
+				unsigned int *id_len);
+
+typedef struct ssl_comp_st
+	{
+	int id;
+	const char *name;
+#ifndef OPENSSL_NO_COMP
+	COMP_METHOD *method;
+#else
+	char *method;
+#endif
+	} SSL_COMP;
+
+DECLARE_STACK_OF(SSL_COMP)
+
+struct ssl_ctx_st
+	{
+	SSL_METHOD *method;
+
+	STACK_OF(SSL_CIPHER) *cipher_list;
+	/* same as above but sorted for lookup */
+	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+
+	struct x509_store_st /* X509_STORE */ *cert_store;
+	struct lhash_st /* LHASH */ *sessions;	/* a set of SSL_SESSIONs */
+	/* Most session-ids that will be cached, default is
+	 * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. */
+	unsigned long session_cache_size;
+	struct ssl_session_st *session_cache_head;
+	struct ssl_session_st *session_cache_tail;
+
+	/* This can have one of 2 values, ored together,
+	 * SSL_SESS_CACHE_CLIENT,
+	 * SSL_SESS_CACHE_SERVER,
+	 * Default is SSL_SESSION_CACHE_SERVER, which means only
+	 * SSL_accept which cache SSL_SESSIONS. */
+	int session_cache_mode;
+
+	/* If timeout is not 0, it is the default timeout value set
+	 * when SSL_new() is called.  This has been put in to make
+	 * life easier to set things up */
+	long session_timeout;
+
+	/* If this callback is not null, it will be called each
+	 * time a session id is added to the cache.  If this function
+	 * returns 1, it means that the callback will do a
+	 * SSL_SESSION_free() when it has finished using it.  Otherwise,
+	 * on 0, it means the callback has finished with it.
+	 * If remove_session_cb is not null, it will be called when
+	 * a session-id is removed from the cache.  After the call,
+	 * OpenSSL will SSL_SESSION_free() it. */
+	int (*new_session_cb)(struct ssl_st *ssl,SSL_SESSION *sess);
+	void (*remove_session_cb)(struct ssl_ctx_st *ctx,SSL_SESSION *sess);
+	SSL_SESSION *(*get_session_cb)(struct ssl_st *ssl,
+		unsigned char *data,int len,int *copy);
+
+	struct
+		{
+		int sess_connect;	/* SSL new conn - started */
+		int sess_connect_renegotiate;/* SSL reneg - requested */
+		int sess_connect_good;	/* SSL new conne/reneg - finished */
+		int sess_accept;	/* SSL new accept - started */
+		int sess_accept_renegotiate;/* SSL reneg - requested */
+		int sess_accept_good;	/* SSL accept/reneg - finished */
+		int sess_miss;		/* session lookup misses  */
+		int sess_timeout;	/* reuse attempt on timeouted session */
+		int sess_cache_full;	/* session removed due to full cache */
+		int sess_hit;		/* session reuse actually done */
+		int sess_cb_hit;	/* session-id that was not
+					 * in the cache was
+					 * passed back via the callback.  This
+					 * indicates that the application is
+					 * supplying session-id's from other
+					 * processes - spooky :-) */
+		} stats;
+
+	int references;
+
+	/* if defined, these override the X509_verify_cert() calls */
+	int (*app_verify_callback)(X509_STORE_CTX *, void *);
+	void *app_verify_arg;
+	/* before OpenSSL 0.9.7, 'app_verify_arg' was ignored
+	 * ('app_verify_callback' was called with just one argument) */
+
+	/* Default password callback. */
+	pem_password_cb *default_passwd_callback;
+
+	/* Default password callback user data. */
+	void *default_passwd_callback_userdata;
+
+	/* get client cert callback */
+	int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
+
+    /* cookie generate callback */
+    int (*app_gen_cookie_cb)(SSL *ssl, unsigned char *cookie, 
+        unsigned int *cookie_len);
+
+    /* verify cookie callback */
+    int (*app_verify_cookie_cb)(SSL *ssl, unsigned char *cookie, 
+        unsigned int cookie_len);
+
+	CRYPTO_EX_DATA ex_data;
+
+	const EVP_MD *rsa_md5;/* For SSLv2 - name is 'ssl2-md5' */
+	const EVP_MD *md5;	/* For SSLv3/TLSv1 'ssl3-md5' */
+	const EVP_MD *sha1;   /* For SSLv3/TLSv1 'ssl3->sha1' */
+
+	STACK_OF(X509) *extra_certs;
+	STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */
+
+
+	/* Default values used when no per-SSL value is defined follow */
+
+	void (*info_callback)(const SSL *ssl,int type,int val); /* used if SSL's info_callback is NULL */
+
+	/* what we put in client cert requests */
+	STACK_OF(X509_NAME) *client_CA;
+
+
+	/* Default values to use in SSL structures follow (these are copied by SSL_new) */
+
+	unsigned long options;
+	unsigned long mode;
+	long max_cert_list;
+
+	struct cert_st /* CERT */ *cert;
+	int read_ahead;
+
+	/* callback that allows applications to peek at protocol messages */
+	void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
+	void *msg_callback_arg;
+
+	int verify_mode;
+	unsigned int sid_ctx_length;
+	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+	int (*default_verify_callback)(int ok,X509_STORE_CTX *ctx); /* called 'verify_callback' in the SSL */
+
+	/* Default generate session ID callback. */
+	GEN_SESSION_CB generate_session_id;
+
+	X509_VERIFY_PARAM *param;
+
+#if 0
+	int purpose;		/* Purpose setting */
+	int trust;		/* Trust setting */
+#endif
+
+	int quiet_shutdown;
+	};
+
+#define SSL_SESS_CACHE_OFF			0x0000
+#define SSL_SESS_CACHE_CLIENT			0x0001
+#define SSL_SESS_CACHE_SERVER			0x0002
+#define SSL_SESS_CACHE_BOTH	(SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER)
+#define SSL_SESS_CACHE_NO_AUTO_CLEAR		0x0080
+/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */
+#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP	0x0100
+#define SSL_SESS_CACHE_NO_INTERNAL_STORE	0x0200
+#define SSL_SESS_CACHE_NO_INTERNAL \
+	(SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
+
+  struct lhash_st *SSL_CTX_sessions(SSL_CTX *ctx);
+#define SSL_CTX_sess_number(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
+#define SSL_CTX_sess_connect(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL)
+#define SSL_CTX_sess_connect_good(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL)
+#define SSL_CTX_sess_connect_renegotiate(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL)
+#define SSL_CTX_sess_accept(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL)
+#define SSL_CTX_sess_accept_renegotiate(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL)
+#define SSL_CTX_sess_accept_good(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL)
+#define SSL_CTX_sess_hits(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL)
+#define SSL_CTX_sess_cb_hits(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL)
+#define SSL_CTX_sess_misses(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL)
+#define SSL_CTX_sess_timeouts(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
+#define SSL_CTX_sess_cache_full(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
+
+#define SSL_CTX_sess_set_new_cb(ctx,cb)	((ctx)->new_session_cb=(cb))
+#define SSL_CTX_sess_get_new_cb(ctx)	((ctx)->new_session_cb)
+#define SSL_CTX_sess_set_remove_cb(ctx,cb)	((ctx)->remove_session_cb=(cb))
+#define SSL_CTX_sess_get_remove_cb(ctx)	((ctx)->remove_session_cb)
+#define SSL_CTX_sess_set_get_cb(ctx,cb)	((ctx)->get_session_cb=(cb))
+#define SSL_CTX_sess_get_get_cb(ctx)	((ctx)->get_session_cb)
+#define SSL_CTX_set_info_callback(ctx,cb)	((ctx)->info_callback=(cb))
+#define SSL_CTX_get_info_callback(ctx)		((ctx)->info_callback)
+#define SSL_CTX_set_client_cert_cb(ctx,cb)	((ctx)->client_cert_cb=(cb))
+#define SSL_CTX_get_client_cert_cb(ctx)		((ctx)->client_cert_cb)
+#define SSL_CTX_set_cookie_generate_cb(ctx,cb) ((ctx)->app_gen_cookie_cb=(cb))
+#define SSL_CTX_set_cookie_verify_cb(ctx,cb) ((ctx)->app_verify_cookie_cb=(cb))
+
+#define SSL_NOTHING	1
+#define SSL_WRITING	2
+#define SSL_READING	3
+#define SSL_X509_LOOKUP	4
+
+/* These will only be used when doing non-blocking IO */
+#define SSL_want_nothing(s)	(SSL_want(s) == SSL_NOTHING)
+#define SSL_want_read(s)	(SSL_want(s) == SSL_READING)
+#define SSL_want_write(s)	(SSL_want(s) == SSL_WRITING)
+#define SSL_want_x509_lookup(s)	(SSL_want(s) == SSL_X509_LOOKUP)
+
+struct ssl_st
+	{
+	/* protocol version
+	 * (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, DTLS1_VERSION)
+	 */
+	int version;
+	int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
+
+	SSL_METHOD *method; /* SSLv3 */
+
+	/* There are 2 BIO's even though they are normally both the
+	 * same.  This is so data can be read and written to different
+	 * handlers */
+
+#ifndef OPENSSL_NO_BIO
+	BIO *rbio; /* used by SSL_read */
+	BIO *wbio; /* used by SSL_write */
+	BIO *bbio; /* used during session-id reuse to concatenate
+		    * messages */
+#else
+	char *rbio; /* used by SSL_read */
+	char *wbio; /* used by SSL_write */
+	char *bbio;
+#endif
+	/* This holds a variable that indicates what we were doing
+	 * when a 0 or -1 is returned.  This is needed for
+	 * non-blocking IO so we know what request needs re-doing when
+	 * in SSL_accept or SSL_connect */
+	int rwstate;
+
+	/* true when we are actually in SSL_accept() or SSL_connect() */
+	int in_handshake;
+	int (*handshake_func)(SSL *);
+
+	/* Imagine that here's a boolean member "init" that is
+	 * switched as soon as SSL_set_{accept/connect}_state
+	 * is called for the first time, so that "state" and
+	 * "handshake_func" are properly initialized.  But as
+	 * handshake_func is == 0 until then, we use this
+	 * test instead of an "init" member.
+	 */
+
+	int server;	/* are we the server side? - mostly used by SSL_clear*/
+
+	int new_session;/* 1 if we are to use a new session.
+	                 * 2 if we are a server and are inside a handshake
+	                 *   (i.e. not just sending a HelloRequest)
+	                 * NB: For servers, the 'new' session may actually be a previously
+	                 * cached session or even the previous session unless
+	                 * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */
+	int quiet_shutdown;/* don't send shutdown packets */
+	int shutdown;	/* we have shut things down, 0x01 sent, 0x02
+			 * for received */
+	int state;	/* where we are */
+	int rstate;	/* where we are when reading */
+
+	BUF_MEM *init_buf;	/* buffer used during init */
+	void *init_msg;   	/* pointer to handshake message body, set by ssl3_get_message() */
+	int init_num;		/* amount read/written */
+	int init_off;		/* amount read/written */
+
+	/* used internally to point at a raw packet */
+	unsigned char *packet;
+	unsigned int packet_length;
+
+	struct ssl2_state_st *s2; /* SSLv2 variables */
+	struct ssl3_state_st *s3; /* SSLv3 variables */
+	struct dtls1_state_st *d1; /* DTLSv1 variables */
+
+	int read_ahead;		/* Read as many input bytes as possible
+	               	 	 * (for non-blocking reads) */
+
+	/* callback that allows applications to peek at protocol messages */
+	void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
+	void *msg_callback_arg;
+
+	int hit;		/* reusing a previous session */
+
+	X509_VERIFY_PARAM *param;
+
+#if 0
+	int purpose;		/* Purpose setting */
+	int trust;		/* Trust setting */
+#endif
+
+	/* crypto */
+	STACK_OF(SSL_CIPHER) *cipher_list;
+	STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+
+	/* These are the ones being used, the ones in SSL_SESSION are
+	 * the ones to be 'copied' into these ones */
+
+	EVP_CIPHER_CTX *enc_read_ctx;		/* cryptographic state */
+	const EVP_MD *read_hash;		/* used for mac generation */
+#ifndef OPENSSL_NO_COMP
+	COMP_CTX *expand;			/* uncompress */
+#else
+	char *expand;
+#endif
+
+	EVP_CIPHER_CTX *enc_write_ctx;		/* cryptographic state */
+	const EVP_MD *write_hash;		/* used for mac generation */
+#ifndef OPENSSL_NO_COMP
+	COMP_CTX *compress;			/* compression */
+#else
+	char *compress;	
+#endif
+
+	/* session info */
+
+	/* client cert? */
+	/* This is used to hold the server certificate used */
+	struct cert_st /* CERT */ *cert;
+
+	/* the session_id_context is used to ensure sessions are only reused
+	 * in the appropriate context */
+	unsigned int sid_ctx_length;
+	unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+
+	/* This can also be in the session once a session is established */
+	SSL_SESSION *session;
+
+	/* Default generate session ID callback. */
+	GEN_SESSION_CB generate_session_id;
+
+	/* Used in SSL2 and SSL3 */
+	int verify_mode;	/* 0 don't care about verify failure.
+				 * 1 fail if verify fails */
+	int (*verify_callback)(int ok,X509_STORE_CTX *ctx); /* fail if callback returns 0 */
+
+	void (*info_callback)(const SSL *ssl,int type,int val); /* optional informational callback */
+
+	int error;		/* error bytes to be written */
+	int error_code;		/* actual code */
+
+#ifndef OPENSSL_NO_KRB5
+	KSSL_CTX *kssl_ctx;     /* Kerberos 5 context */
+#endif	/* OPENSSL_NO_KRB5 */
+
+	SSL_CTX *ctx;
+	/* set this flag to 1 and a sleep(1) is put into all SSL_read()
+	 * and SSL_write() calls, good for nbio debuging :-) */
+	int debug;	
+
+	/* extra application data */
+	long verify_result;
+	CRYPTO_EX_DATA ex_data;
+
+	/* for server side, keep the list of CA_dn we can use */
+	STACK_OF(X509_NAME) *client_CA;
+
+	int references;
+	unsigned long options; /* protocol behaviour */
+	unsigned long mode; /* API behaviour */
+	long max_cert_list;
+	int first_packet;
+	int client_version;	/* what was passed, used for
+				 * SSLv3/TLS rollback check */
+	};
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <openssl/ssl2.h>
+#include <openssl/ssl3.h>
+#include <openssl/tls1.h> /* This is mostly sslv3 with a few tweaks */
+#include <openssl/dtls1.h> /* Datagram TLS */
+#include <openssl/ssl23.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* compatibility */
+#define SSL_set_app_data(s,arg)		(SSL_set_ex_data(s,0,(char *)arg))
+#define SSL_get_app_data(s)		(SSL_get_ex_data(s,0))
+#define SSL_SESSION_set_app_data(s,a)	(SSL_SESSION_set_ex_data(s,0,(char *)a))
+#define SSL_SESSION_get_app_data(s)	(SSL_SESSION_get_ex_data(s,0))
+#define SSL_CTX_get_app_data(ctx)	(SSL_CTX_get_ex_data(ctx,0))
+#define SSL_CTX_set_app_data(ctx,arg)	(SSL_CTX_set_ex_data(ctx,0,(char *)arg))
+
+/* The following are the possible values for ssl->state are are
+ * used to indicate where we are up to in the SSL connection establishment.
+ * The macros that follow are about the only things you should need to use
+ * and even then, only when using non-blocking IO.
+ * It can also be useful to work out where you were when the connection
+ * failed */
+
+#define SSL_ST_CONNECT			0x1000
+#define SSL_ST_ACCEPT			0x2000
+#define SSL_ST_MASK			0x0FFF
+#define SSL_ST_INIT			(SSL_ST_CONNECT|SSL_ST_ACCEPT)
+#define SSL_ST_BEFORE			0x4000
+#define SSL_ST_OK			0x03
+#define SSL_ST_RENEGOTIATE		(0x04|SSL_ST_INIT)
+
+#define SSL_CB_LOOP			0x01
+#define SSL_CB_EXIT			0x02
+#define SSL_CB_READ			0x04
+#define SSL_CB_WRITE			0x08
+#define SSL_CB_ALERT			0x4000 /* used in callback */
+#define SSL_CB_READ_ALERT		(SSL_CB_ALERT|SSL_CB_READ)
+#define SSL_CB_WRITE_ALERT		(SSL_CB_ALERT|SSL_CB_WRITE)
+#define SSL_CB_ACCEPT_LOOP		(SSL_ST_ACCEPT|SSL_CB_LOOP)
+#define SSL_CB_ACCEPT_EXIT		(SSL_ST_ACCEPT|SSL_CB_EXIT)
+#define SSL_CB_CONNECT_LOOP		(SSL_ST_CONNECT|SSL_CB_LOOP)
+#define SSL_CB_CONNECT_EXIT		(SSL_ST_CONNECT|SSL_CB_EXIT)
+#define SSL_CB_HANDSHAKE_START		0x10
+#define SSL_CB_HANDSHAKE_DONE		0x20
+
+/* Is the SSL_connection established? */
+#define SSL_get_state(a)		SSL_state(a)
+#define SSL_is_init_finished(a)		(SSL_state(a) == SSL_ST_OK)
+#define SSL_in_init(a)			(SSL_state(a)&SSL_ST_INIT)
+#define SSL_in_before(a)		(SSL_state(a)&SSL_ST_BEFORE)
+#define SSL_in_connect_init(a)		(SSL_state(a)&SSL_ST_CONNECT)
+#define SSL_in_accept_init(a)		(SSL_state(a)&SSL_ST_ACCEPT)
+
+/* The following 2 states are kept in ssl->rstate when reads fail,
+ * you should not need these */
+#define SSL_ST_READ_HEADER			0xF0
+#define SSL_ST_READ_BODY			0xF1
+#define SSL_ST_READ_DONE			0xF2
+
+/* Obtain latest Finished message
+ *   -- that we sent (SSL_get_finished)
+ *   -- that we expected from peer (SSL_get_peer_finished).
+ * Returns length (0 == no Finished so far), copies up to 'count' bytes. */
+size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
+size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
+
+/* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options
+ * are 'ored' with SSL_VERIFY_PEER if they are desired */
+#define SSL_VERIFY_NONE			0x00
+#define SSL_VERIFY_PEER			0x01
+#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT	0x02
+#define SSL_VERIFY_CLIENT_ONCE		0x04
+
+#define OpenSSL_add_ssl_algorithms()	SSL_library_init()
+#define SSLeay_add_ssl_algorithms()	SSL_library_init()
+
+/* this is for backward compatibility */
+#if 0 /* NEW_SSLEAY */
+#define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c)
+#define SSL_set_pref_cipher(c,n)	SSL_set_cipher_list(c,n)
+#define SSL_add_session(a,b)            SSL_CTX_add_session((a),(b))
+#define SSL_remove_session(a,b)		SSL_CTX_remove_session((a),(b))
+#define SSL_flush_sessions(a,b)		SSL_CTX_flush_sessions((a),(b))
+#endif
+/* More backward compatibility */
+#define SSL_get_cipher(s) \
+		SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+#define SSL_get_cipher_bits(s,np) \
+		SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np)
+#define SSL_get_cipher_version(s) \
+		SSL_CIPHER_get_version(SSL_get_current_cipher(s))
+#define SSL_get_cipher_name(s) \
+		SSL_CIPHER_get_name(SSL_get_current_cipher(s))
+#define SSL_get_time(a)		SSL_SESSION_get_time(a)
+#define SSL_set_time(a,b)	SSL_SESSION_set_time((a),(b))
+#define SSL_get_timeout(a)	SSL_SESSION_get_timeout(a)
+#define SSL_set_timeout(a,b)	SSL_SESSION_set_timeout((a),(b))
+
+#if 1 /*SSLEAY_MACROS*/
+#define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
+#define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)
+#define PEM_read_SSL_SESSION(fp,x,cb,u) (SSL_SESSION *)PEM_ASN1_read( \
+	(char *(*)())d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,fp,(char **)x,cb,u)
+#define PEM_read_bio_SSL_SESSION(bp,x,cb,u) PEM_ASN1_read_bio_of(SSL_SESSION,d2i_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,cb,u)
+#define PEM_write_SSL_SESSION(fp,x) \
+	PEM_ASN1_write((int (*)())i2d_SSL_SESSION, \
+		PEM_STRING_SSL_SESSION,fp, (char *)x, NULL,NULL,0,NULL,NULL)
+#define PEM_write_bio_SSL_SESSION(bp,x) \
+	PEM_ASN1_write_bio_of(SSL_SESSION,i2d_SSL_SESSION,PEM_STRING_SSL_SESSION,bp,x,NULL,NULL,0,NULL,NULL)
+#endif
+
+#define SSL_AD_REASON_OFFSET		1000
+/* These alert types are for SSLv3 and TLSv1 */
+#define SSL_AD_CLOSE_NOTIFY		SSL3_AD_CLOSE_NOTIFY
+#define SSL_AD_UNEXPECTED_MESSAGE	SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
+#define SSL_AD_BAD_RECORD_MAC		SSL3_AD_BAD_RECORD_MAC     /* fatal */
+#define SSL_AD_DECRYPTION_FAILED	TLS1_AD_DECRYPTION_FAILED
+#define SSL_AD_RECORD_OVERFLOW		TLS1_AD_RECORD_OVERFLOW
+#define SSL_AD_DECOMPRESSION_FAILURE	SSL3_AD_DECOMPRESSION_FAILURE/* fatal */
+#define SSL_AD_HANDSHAKE_FAILURE	SSL3_AD_HANDSHAKE_FAILURE/* fatal */
+#define SSL_AD_NO_CERTIFICATE		SSL3_AD_NO_CERTIFICATE /* Not for TLS */
+#define SSL_AD_BAD_CERTIFICATE		SSL3_AD_BAD_CERTIFICATE
+#define SSL_AD_UNSUPPORTED_CERTIFICATE	SSL3_AD_UNSUPPORTED_CERTIFICATE
+#define SSL_AD_CERTIFICATE_REVOKED	SSL3_AD_CERTIFICATE_REVOKED
+#define SSL_AD_CERTIFICATE_EXPIRED	SSL3_AD_CERTIFICATE_EXPIRED
+#define SSL_AD_CERTIFICATE_UNKNOWN	SSL3_AD_CERTIFICATE_UNKNOWN
+#define SSL_AD_ILLEGAL_PARAMETER	SSL3_AD_ILLEGAL_PARAMETER   /* fatal */
+#define SSL_AD_UNKNOWN_CA		TLS1_AD_UNKNOWN_CA	/* fatal */
+#define SSL_AD_ACCESS_DENIED		TLS1_AD_ACCESS_DENIED	/* fatal */
+#define SSL_AD_DECODE_ERROR		TLS1_AD_DECODE_ERROR	/* fatal */
+#define SSL_AD_DECRYPT_ERROR		TLS1_AD_DECRYPT_ERROR
+#define SSL_AD_EXPORT_RESTRICTION	TLS1_AD_EXPORT_RESTRICTION/* fatal */
+#define SSL_AD_PROTOCOL_VERSION		TLS1_AD_PROTOCOL_VERSION /* fatal */
+#define SSL_AD_INSUFFICIENT_SECURITY	TLS1_AD_INSUFFICIENT_SECURITY/* fatal */
+#define SSL_AD_INTERNAL_ERROR		TLS1_AD_INTERNAL_ERROR	/* fatal */
+#define SSL_AD_USER_CANCELLED		TLS1_AD_USER_CANCELLED
+#define SSL_AD_NO_RENEGOTIATION		TLS1_AD_NO_RENEGOTIATION
+
+#define SSL_ERROR_NONE			0
+#define SSL_ERROR_SSL			1
+#define SSL_ERROR_WANT_READ		2
+#define SSL_ERROR_WANT_WRITE		3
+#define SSL_ERROR_WANT_X509_LOOKUP	4
+#define SSL_ERROR_SYSCALL		5 /* look at error stack/return value/errno */
+#define SSL_ERROR_ZERO_RETURN		6
+#define SSL_ERROR_WANT_CONNECT		7
+#define SSL_ERROR_WANT_ACCEPT		8
+
+#define SSL_CTRL_NEED_TMP_RSA			1
+#define SSL_CTRL_SET_TMP_RSA			2
+#define SSL_CTRL_SET_TMP_DH			3
+#define SSL_CTRL_SET_TMP_ECDH			4
+#define SSL_CTRL_SET_TMP_RSA_CB			5
+#define SSL_CTRL_SET_TMP_DH_CB			6
+#define SSL_CTRL_SET_TMP_ECDH_CB		7
+
+#define SSL_CTRL_GET_SESSION_REUSED		8
+#define SSL_CTRL_GET_CLIENT_CERT_REQUEST	9
+#define SSL_CTRL_GET_NUM_RENEGOTIATIONS		10
+#define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS	11
+#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS	12
+#define SSL_CTRL_GET_FLAGS			13
+#define SSL_CTRL_EXTRA_CHAIN_CERT		14
+
+#define SSL_CTRL_SET_MSG_CALLBACK               15
+#define SSL_CTRL_SET_MSG_CALLBACK_ARG           16
+
+/* only applies to datagram connections */
+#define SSL_CTRL_SET_MTU                17
+/* Stats */
+#define SSL_CTRL_SESS_NUMBER			20
+#define SSL_CTRL_SESS_CONNECT			21
+#define SSL_CTRL_SESS_CONNECT_GOOD		22
+#define SSL_CTRL_SESS_CONNECT_RENEGOTIATE	23
+#define SSL_CTRL_SESS_ACCEPT			24
+#define SSL_CTRL_SESS_ACCEPT_GOOD		25
+#define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE	26
+#define SSL_CTRL_SESS_HIT			27
+#define SSL_CTRL_SESS_CB_HIT			28
+#define SSL_CTRL_SESS_MISSES			29
+#define SSL_CTRL_SESS_TIMEOUTS			30
+#define SSL_CTRL_SESS_CACHE_FULL		31
+#define SSL_CTRL_OPTIONS			32
+#define SSL_CTRL_MODE				33
+
+#define SSL_CTRL_GET_READ_AHEAD			40
+#define SSL_CTRL_SET_READ_AHEAD			41
+#define SSL_CTRL_SET_SESS_CACHE_SIZE		42
+#define SSL_CTRL_GET_SESS_CACHE_SIZE		43
+#define SSL_CTRL_SET_SESS_CACHE_MODE		44
+#define SSL_CTRL_GET_SESS_CACHE_MODE		45
+
+#define SSL_CTRL_GET_MAX_CERT_LIST		50
+#define SSL_CTRL_SET_MAX_CERT_LIST		51
+
+#define SSL_session_reused(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
+#define SSL_num_renegotiations(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL)
+#define SSL_clear_num_renegotiations(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL)
+#define SSL_total_renegotiations(ssl) \
+	SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL)
+
+#define SSL_CTX_need_tmp_RSA(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL)
+#define SSL_CTX_set_tmp_rsa(ctx,rsa) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
+#define SSL_CTX_set_tmp_dh(ctx,dh) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+#define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+
+#define SSL_need_tmp_RSA(ssl) \
+	SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL)
+#define SSL_set_tmp_rsa(ssl,rsa) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
+#define SSL_set_tmp_dh(ssl,dh) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
+#define SSL_set_tmp_ecdh(ssl,ecdh) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
+
+#define SSL_CTX_add_extra_chain_cert(ctx,x509) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
+
+#ifndef OPENSSL_NO_BIO
+BIO_METHOD *BIO_f_ssl(void);
+BIO *BIO_new_ssl(SSL_CTX *ctx,int client);
+BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
+BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
+int BIO_ssl_copy_session_id(BIO *to,BIO *from);
+void BIO_ssl_shutdown(BIO *ssl_bio);
+
+#endif
+
+int	SSL_CTX_set_cipher_list(SSL_CTX *,const char *str);
+SSL_CTX *SSL_CTX_new(SSL_METHOD *meth);
+void	SSL_CTX_free(SSL_CTX *);
+long SSL_CTX_set_timeout(SSL_CTX *ctx,long t);
+long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
+void SSL_CTX_set_cert_store(SSL_CTX *,X509_STORE *);
+int SSL_want(const SSL *s);
+int	SSL_clear(SSL *s);
+
+void	SSL_CTX_flush_sessions(SSL_CTX *ctx,long tm);
+
+SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
+int	SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits);
+char *	SSL_CIPHER_get_version(const SSL_CIPHER *c);
+const char *	SSL_CIPHER_get_name(const SSL_CIPHER *c);
+
+int	SSL_get_fd(const SSL *s);
+int	SSL_get_rfd(const SSL *s);
+int	SSL_get_wfd(const SSL *s);
+const char  * SSL_get_cipher_list(const SSL *s,int n);
+char *	SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
+int	SSL_get_read_ahead(const SSL * s);
+int	SSL_pending(const SSL *s);
+#ifndef OPENSSL_NO_SOCK
+int	SSL_set_fd(SSL *s, int fd);
+int	SSL_set_rfd(SSL *s, int fd);
+int	SSL_set_wfd(SSL *s, int fd);
+#endif
+#ifndef OPENSSL_NO_BIO
+void	SSL_set_bio(SSL *s, BIO *rbio,BIO *wbio);
+BIO *	SSL_get_rbio(const SSL *s);
+BIO *	SSL_get_wbio(const SSL *s);
+#endif
+int	SSL_set_cipher_list(SSL *s, const char *str);
+void	SSL_set_read_ahead(SSL *s, int yes);
+int	SSL_get_verify_mode(const SSL *s);
+int	SSL_get_verify_depth(const SSL *s);
+int	(*SSL_get_verify_callback(const SSL *s))(int,X509_STORE_CTX *);
+void	SSL_set_verify(SSL *s, int mode,
+		       int (*callback)(int ok,X509_STORE_CTX *ctx));
+void	SSL_set_verify_depth(SSL *s, int depth);
+#ifndef OPENSSL_NO_RSA
+int	SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
+#endif
+int	SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
+int	SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+int	SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
+int	SSL_use_certificate(SSL *ssl, X509 *x);
+int	SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
+
+#ifndef OPENSSL_NO_STDIO
+int	SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
+int	SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
+int	SSL_use_certificate_file(SSL *ssl, const char *file, int type);
+int	SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+int	SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
+int	SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
+int	SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); /* PEM type */
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+int	SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+					    const char *file);
+#ifndef OPENSSL_SYS_VMS
+#ifndef OPENSSL_SYS_MACINTOSH_CLASSIC /* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */
+int	SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
+					   const char *dir);
+#endif
+#endif
+
+#endif
+
+void	SSL_load_error_strings(void );
+const char *SSL_state_string(const SSL *s);
+const char *SSL_rstate_string(const SSL *s);
+const char *SSL_state_string_long(const SSL *s);
+const char *SSL_rstate_string_long(const SSL *s);
+long	SSL_SESSION_get_time(const SSL_SESSION *s);
+long	SSL_SESSION_set_time(SSL_SESSION *s, long t);
+long	SSL_SESSION_get_timeout(const SSL_SESSION *s);
+long	SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
+void	SSL_copy_session_id(SSL *to,const SSL *from);
+
+SSL_SESSION *SSL_SESSION_new(void);
+unsigned long SSL_SESSION_hash(const SSL_SESSION *a);
+int	SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b);
+const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len);
+#ifndef OPENSSL_NO_FP_API
+int	SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses);
+#endif
+#ifndef OPENSSL_NO_BIO
+int	SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
+#endif
+void	SSL_SESSION_free(SSL_SESSION *ses);
+int	i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
+int	SSL_set_session(SSL *to, SSL_SESSION *session);
+int	SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
+int	SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
+int	SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
+int	SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
+int	SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
+					unsigned int id_len);
+SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a,const unsigned char **pp,
+			     long length);
+
+#ifdef HEADER_X509_H
+X509 *	SSL_get_peer_certificate(const SSL *s);
+#endif
+
+STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
+
+int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int,X509_STORE_CTX *);
+void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
+			int (*callback)(int, X509_STORE_CTX *));
+void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg);
+#ifndef OPENSSL_NO_RSA
+int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+#endif
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len);
+int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx,
+	const unsigned char *d, long len);
+int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
+int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
+
+int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+int SSL_check_private_key(const SSL *ctx);
+
+int	SSL_CTX_set_session_id_context(SSL_CTX *ctx,const unsigned char *sid_ctx,
+				       unsigned int sid_ctx_len);
+
+SSL *	SSL_new(SSL_CTX *ctx);
+int	SSL_set_session_id_context(SSL *ssl,const unsigned char *sid_ctx,
+				   unsigned int sid_ctx_len);
+
+int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
+int SSL_set_purpose(SSL *s, int purpose);
+int SSL_CTX_set_trust(SSL_CTX *s, int trust);
+int SSL_set_trust(SSL *s, int trust);
+
+void	SSL_free(SSL *ssl);
+int 	SSL_accept(SSL *ssl);
+int 	SSL_connect(SSL *ssl);
+int 	SSL_read(SSL *ssl,void *buf,int num);
+int 	SSL_peek(SSL *ssl,void *buf,int num);
+int 	SSL_write(SSL *ssl,const void *buf,int num);
+long	SSL_ctrl(SSL *ssl,int cmd, long larg, void *parg);
+long	SSL_callback_ctrl(SSL *, int, void (*)(void));
+long	SSL_CTX_ctrl(SSL_CTX *ctx,int cmd, long larg, void *parg);
+long	SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
+
+int	SSL_get_error(const SSL *s,int ret_code);
+const char *SSL_get_version(const SSL *s);
+
+/* This sets the 'default' SSL version that SSL_new() will create */
+int SSL_CTX_set_ssl_version(SSL_CTX *ctx,SSL_METHOD *meth);
+
+SSL_METHOD *SSLv2_method(void);		/* SSLv2 */
+SSL_METHOD *SSLv2_server_method(void);	/* SSLv2 */
+SSL_METHOD *SSLv2_client_method(void);	/* SSLv2 */
+
+SSL_METHOD *SSLv3_method(void);		/* SSLv3 */
+SSL_METHOD *SSLv3_server_method(void);	/* SSLv3 */
+SSL_METHOD *SSLv3_client_method(void);	/* SSLv3 */
+
+SSL_METHOD *SSLv23_method(void);	/* SSLv3 but can rollback to v2 */
+SSL_METHOD *SSLv23_server_method(void);	/* SSLv3 but can rollback to v2 */
+SSL_METHOD *SSLv23_client_method(void);	/* SSLv3 but can rollback to v2 */
+
+SSL_METHOD *TLSv1_method(void);		/* TLSv1.0 */
+SSL_METHOD *TLSv1_server_method(void);	/* TLSv1.0 */
+SSL_METHOD *TLSv1_client_method(void);	/* TLSv1.0 */
+
+SSL_METHOD *DTLSv1_method(void);		/* DTLSv1.0 */
+SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
+SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
+
+STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
+
+int SSL_do_handshake(SSL *s);
+int SSL_renegotiate(SSL *s);
+int SSL_renegotiate_pending(SSL *s);
+int SSL_shutdown(SSL *s);
+
+SSL_METHOD *SSL_get_ssl_method(SSL *s);
+int SSL_set_ssl_method(SSL *s,SSL_METHOD *method);
+const char *SSL_alert_type_string_long(int value);
+const char *SSL_alert_type_string(int value);
+const char *SSL_alert_desc_string_long(int value);
+const char *SSL_alert_desc_string(int value);
+
+void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
+void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
+STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
+int SSL_add_client_CA(SSL *ssl,X509 *x);
+int SSL_CTX_add_client_CA(SSL_CTX *ctx,X509 *x);
+
+void SSL_set_connect_state(SSL *s);
+void SSL_set_accept_state(SSL *s);
+
+long SSL_get_default_timeout(const SSL *s);
+
+int SSL_library_init(void );
+
+char *SSL_CIPHER_description(SSL_CIPHER *,char *buf,int size);
+STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
+
+SSL *SSL_dup(SSL *ssl);
+
+X509 *SSL_get_certificate(const SSL *ssl);
+/* EVP_PKEY */ struct evp_pkey_st *SSL_get_privatekey(SSL *ssl);
+
+void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx,int mode);
+int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+void SSL_set_quiet_shutdown(SSL *ssl,int mode);
+int SSL_get_quiet_shutdown(const SSL *ssl);
+void SSL_set_shutdown(SSL *ssl,int mode);
+int SSL_get_shutdown(const SSL *ssl);
+int SSL_version(const SSL *ssl);
+int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
+	const char *CApath);
+#define SSL_get0_session SSL_get_session /* just peek at pointer */
+SSL_SESSION *SSL_get_session(const SSL *ssl);
+SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
+SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+void SSL_set_info_callback(SSL *ssl,
+			   void (*cb)(const SSL *ssl,int type,int val));
+void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,int type,int val);
+int SSL_state(const SSL *ssl);
+
+void SSL_set_verify_result(SSL *ssl,long v);
+long SSL_get_verify_result(const SSL *ssl);
+
+int SSL_set_ex_data(SSL *ssl,int idx,void *data);
+void *SSL_get_ex_data(const SSL *ssl,int idx);
+int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_SESSION_set_ex_data(SSL_SESSION *ss,int idx,void *data);
+void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss,int idx);
+int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_CTX_set_ex_data(SSL_CTX *ssl,int idx,void *data);
+void *SSL_CTX_get_ex_data(const SSL_CTX *ssl,int idx);
+int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+
+int SSL_get_ex_data_X509_STORE_CTX_idx(void );
+
+#define SSL_CTX_sess_set_cache_size(ctx,t) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
+#define SSL_CTX_sess_get_cache_size(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL)
+#define SSL_CTX_set_session_cache_mode(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
+#define SSL_CTX_get_session_cache_mode(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL)
+
+#define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx)
+#define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m)
+#define SSL_CTX_get_read_ahead(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL)
+#define SSL_CTX_set_read_ahead(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL)
+#define SSL_CTX_get_max_cert_list(ctx) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+#define SSL_CTX_set_max_cert_list(ctx,m) \
+	SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+#define SSL_get_max_cert_list(ssl) \
+	SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
+#define SSL_set_max_cert_list(ssl,m) \
+	SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
+
+     /* NB: the keylength is only applicable when is_export is true */
+#ifndef OPENSSL_NO_RSA
+void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
+				  RSA *(*cb)(SSL *ssl,int is_export,
+					     int keylength));
+
+void SSL_set_tmp_rsa_callback(SSL *ssl,
+				  RSA *(*cb)(SSL *ssl,int is_export,
+					     int keylength));
+#endif
+#ifndef OPENSSL_NO_DH
+void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
+				 DH *(*dh)(SSL *ssl,int is_export,
+					   int keylength));
+void SSL_set_tmp_dh_callback(SSL *ssl,
+				 DH *(*dh)(SSL *ssl,int is_export,
+					   int keylength));
+#endif
+#ifndef OPENSSL_NO_ECDH
+void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
+				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
+					   int keylength));
+void SSL_set_tmp_ecdh_callback(SSL *ssl,
+				 EC_KEY *(*ecdh)(SSL *ssl,int is_export,
+					   int keylength));
+#endif
+
+#ifndef OPENSSL_NO_COMP
+const COMP_METHOD *SSL_get_current_compression(SSL *s);
+const COMP_METHOD *SSL_get_current_expansion(SSL *s);
+const char *SSL_COMP_get_name(const COMP_METHOD *comp);
+STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
+int SSL_COMP_add_compression_method(int id,COMP_METHOD *cm);
+#else
+const void *SSL_get_current_compression(SSL *s);
+const void *SSL_get_current_expansion(SSL *s);
+const char *SSL_COMP_get_name(const void *comp);
+void *SSL_COMP_get_compression_methods(void);
+int SSL_COMP_add_compression_method(int id,void *cm);
+#endif
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_SSL_strings(void);
+
+/* Error codes for the SSL functions. */
+
+/* Function codes. */
+#define SSL_F_CLIENT_CERTIFICATE			 100
+#define SSL_F_CLIENT_FINISHED				 238
+#define SSL_F_CLIENT_HELLO				 101
+#define SSL_F_CLIENT_MASTER_KEY				 102
+#define SSL_F_D2I_SSL_SESSION				 103
+#define SSL_F_DO_DTLS1_WRITE				 1003
+#define SSL_F_DO_SSL3_WRITE				 104
+#define SSL_F_DTLS1_ACCEPT				 1004
+#define SSL_F_DTLS1_BUFFER_RECORD			 1005
+#define SSL_F_DTLS1_CLIENT_HELLO			 1006
+#define SSL_F_DTLS1_CONNECT				 1007
+#define SSL_F_DTLS1_ENC					 1008
+#define SSL_F_DTLS1_GET_HELLO_VERIFY			 1009
+#define SSL_F_DTLS1_GET_MESSAGE				 1010
+#define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT		 1011
+#define SSL_F_DTLS1_GET_RECORD				 1012
+#define SSL_F_DTLS1_OUTPUT_CERT_CHAIN			 1013
+#define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE		 1014
+#define SSL_F_DTLS1_PROCESS_RECORD			 1015
+#define SSL_F_DTLS1_READ_BYTES				 1016
+#define SSL_F_DTLS1_READ_FAILED				 1001
+#define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST		 1017
+#define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE		 1018
+#define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE		 1019
+#define SSL_F_DTLS1_SEND_CLIENT_VERIFY			 1020
+#define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST		 1002
+#define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE		 1021
+#define SSL_F_DTLS1_SEND_SERVER_HELLO			 1022
+#define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE		 1023
+#define SSL_F_DTLS1_WRITE_APP_DATA_BYTES		 1024
+#define SSL_F_GET_CLIENT_FINISHED			 105
+#define SSL_F_GET_CLIENT_HELLO				 106
+#define SSL_F_GET_CLIENT_MASTER_KEY			 107
+#define SSL_F_GET_SERVER_FINISHED			 108
+#define SSL_F_GET_SERVER_HELLO				 109
+#define SSL_F_GET_SERVER_VERIFY				 110
+#define SSL_F_I2D_SSL_SESSION				 111
+#define SSL_F_READ_N					 112
+#define SSL_F_REQUEST_CERTIFICATE			 113
+#define SSL_F_SERVER_FINISH				 239
+#define SSL_F_SERVER_HELLO				 114
+#define SSL_F_SERVER_VERIFY				 240
+#define SSL_F_SSL23_ACCEPT				 115
+#define SSL_F_SSL23_CLIENT_HELLO			 116
+#define SSL_F_SSL23_CONNECT				 117
+#define SSL_F_SSL23_GET_CLIENT_HELLO			 118
+#define SSL_F_SSL23_GET_SERVER_HELLO			 119
+#define SSL_F_SSL23_PEEK				 237
+#define SSL_F_SSL23_READ				 120
+#define SSL_F_SSL23_WRITE				 121
+#define SSL_F_SSL2_ACCEPT				 122
+#define SSL_F_SSL2_CONNECT				 123
+#define SSL_F_SSL2_ENC_INIT				 124
+#define SSL_F_SSL2_GENERATE_KEY_MATERIAL		 241
+#define SSL_F_SSL2_PEEK					 234
+#define SSL_F_SSL2_READ					 125
+#define SSL_F_SSL2_READ_INTERNAL			 236
+#define SSL_F_SSL2_SET_CERTIFICATE			 126
+#define SSL_F_SSL2_WRITE				 127
+#define SSL_F_SSL3_ACCEPT				 128
+#define SSL_F_SSL3_CALLBACK_CTRL			 233
+#define SSL_F_SSL3_CHANGE_CIPHER_STATE			 129
+#define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM		 130
+#define SSL_F_SSL3_CLIENT_HELLO				 131
+#define SSL_F_SSL3_CONNECT				 132
+#define SSL_F_SSL3_CTRL					 213
+#define SSL_F_SSL3_CTX_CTRL				 133
+#define SSL_F_SSL3_ENC					 134
+#define SSL_F_SSL3_GENERATE_KEY_BLOCK			 238
+#define SSL_F_SSL3_GET_CERTIFICATE_REQUEST		 135
+#define SSL_F_SSL3_GET_CERT_VERIFY			 136
+#define SSL_F_SSL3_GET_CLIENT_CERTIFICATE		 137
+#define SSL_F_SSL3_GET_CLIENT_HELLO			 138
+#define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE		 139
+#define SSL_F_SSL3_GET_FINISHED				 140
+#define SSL_F_SSL3_GET_KEY_EXCHANGE			 141
+#define SSL_F_SSL3_GET_MESSAGE				 142
+#define SSL_F_SSL3_GET_RECORD				 143
+#define SSL_F_SSL3_GET_SERVER_CERTIFICATE		 144
+#define SSL_F_SSL3_GET_SERVER_DONE			 145
+#define SSL_F_SSL3_GET_SERVER_HELLO			 146
+#define SSL_F_SSL3_OUTPUT_CERT_CHAIN			 147
+#define SSL_F_SSL3_PEEK					 235
+#define SSL_F_SSL3_READ_BYTES				 148
+#define SSL_F_SSL3_READ_N				 149
+#define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST		 150
+#define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE		 151
+#define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE		 152
+#define SSL_F_SSL3_SEND_CLIENT_VERIFY			 153
+#define SSL_F_SSL3_SEND_SERVER_CERTIFICATE		 154
+#define SSL_F_SSL3_SEND_SERVER_HELLO			 242
+#define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE		 155
+#define SSL_F_SSL3_SETUP_BUFFERS			 156
+#define SSL_F_SSL3_SETUP_KEY_BLOCK			 157
+#define SSL_F_SSL3_WRITE_BYTES				 158
+#define SSL_F_SSL3_WRITE_PENDING			 159
+#define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK	 215
+#define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK	 216
+#define SSL_F_SSL_BAD_METHOD				 160
+#define SSL_F_SSL_BYTES_TO_CIPHER_LIST			 161
+#define SSL_F_SSL_CERT_DUP				 221
+#define SSL_F_SSL_CERT_INST				 222
+#define SSL_F_SSL_CERT_INSTANTIATE			 214
+#define SSL_F_SSL_CERT_NEW				 162
+#define SSL_F_SSL_CHECK_PRIVATE_KEY			 163
+#define SSL_F_SSL_CIPHER_PROCESS_RULESTR		 230
+#define SSL_F_SSL_CIPHER_STRENGTH_SORT			 231
+#define SSL_F_SSL_CLEAR					 164
+#define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD		 165
+#define SSL_F_SSL_CREATE_CIPHER_LIST			 166
+#define SSL_F_SSL_CTRL					 232
+#define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY			 168
+#define SSL_F_SSL_CTX_NEW				 169
+#define SSL_F_SSL_CTX_SET_CIPHER_LIST			 1026
+#define SSL_F_SSL_CTX_SET_PURPOSE			 226
+#define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT		 219
+#define SSL_F_SSL_CTX_SET_SSL_VERSION			 170
+#define SSL_F_SSL_CTX_SET_TRUST				 229
+#define SSL_F_SSL_CTX_USE_CERTIFICATE			 171
+#define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1		 172
+#define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE	 220
+#define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE		 173
+#define SSL_F_SSL_CTX_USE_PRIVATEKEY			 174
+#define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1		 175
+#define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE		 176
+#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY			 177
+#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1		 178
+#define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE		 179
+#define SSL_F_SSL_DO_HANDSHAKE				 180
+#define SSL_F_SSL_GET_NEW_SESSION			 181
+#define SSL_F_SSL_GET_PREV_SESSION			 217
+#define SSL_F_SSL_GET_SERVER_SEND_CERT			 182
+#define SSL_F_SSL_GET_SIGN_PKEY				 183
+#define SSL_F_SSL_INIT_WBIO_BUFFER			 184
+#define SSL_F_SSL_LOAD_CLIENT_CA_FILE			 185
+#define SSL_F_SSL_NEW					 186
+#define SSL_F_SSL_PEEK					 1025
+#define SSL_F_SSL_READ					 223
+#define SSL_F_SSL_RSA_PRIVATE_DECRYPT			 187
+#define SSL_F_SSL_RSA_PUBLIC_ENCRYPT			 188
+#define SSL_F_SSL_SESSION_NEW				 189
+#define SSL_F_SSL_SESSION_PRINT_FP			 190
+#define SSL_F_SSL_SESS_CERT_NEW				 225
+#define SSL_F_SSL_SET_CERT				 191
+#define SSL_F_SSL_SET_CIPHER_LIST			 1027
+#define SSL_F_SSL_SET_FD				 192
+#define SSL_F_SSL_SET_PKEY				 193
+#define SSL_F_SSL_SET_PURPOSE				 227
+#define SSL_F_SSL_SET_RFD				 194
+#define SSL_F_SSL_SET_SESSION				 195
+#define SSL_F_SSL_SET_SESSION_ID_CONTEXT		 218
+#define SSL_F_SSL_SET_TRUST				 228
+#define SSL_F_SSL_SET_WFD				 196
+#define SSL_F_SSL_SHUTDOWN				 224
+#define SSL_F_SSL_UNDEFINED_CONST_FUNCTION		 243
+#define SSL_F_SSL_UNDEFINED_FUNCTION			 197
+#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION		 244
+#define SSL_F_SSL_USE_CERTIFICATE			 198
+#define SSL_F_SSL_USE_CERTIFICATE_ASN1			 199
+#define SSL_F_SSL_USE_CERTIFICATE_FILE			 200
+#define SSL_F_SSL_USE_PRIVATEKEY			 201
+#define SSL_F_SSL_USE_PRIVATEKEY_ASN1			 202
+#define SSL_F_SSL_USE_PRIVATEKEY_FILE			 203
+#define SSL_F_SSL_USE_RSAPRIVATEKEY			 204
+#define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1		 205
+#define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE		 206
+#define SSL_F_SSL_VERIFY_CERT_CHAIN			 207
+#define SSL_F_SSL_WRITE					 208
+#define SSL_F_TLS1_CHANGE_CIPHER_STATE			 209
+#define SSL_F_TLS1_ENC					 210
+#define SSL_F_TLS1_SETUP_KEY_BLOCK			 211
+#define SSL_F_WRITE_PENDING				 212
+
+/* Reason codes. */
+#define SSL_R_APP_DATA_IN_HANDSHAKE			 100
+#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
+#define SSL_R_BAD_ALERT_RECORD				 101
+#define SSL_R_BAD_AUTHENTICATION_TYPE			 102
+#define SSL_R_BAD_CHANGE_CIPHER_SPEC			 103
+#define SSL_R_BAD_CHECKSUM				 104
+#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK		 106
+#define SSL_R_BAD_DECOMPRESSION				 107
+#define SSL_R_BAD_DH_G_LENGTH				 108
+#define SSL_R_BAD_DH_PUB_KEY_LENGTH			 109
+#define SSL_R_BAD_DH_P_LENGTH				 110
+#define SSL_R_BAD_DIGEST_LENGTH				 111
+#define SSL_R_BAD_DSA_SIGNATURE				 112
+#define SSL_R_BAD_ECC_CERT				 1117
+#define SSL_R_BAD_ECDSA_SIGNATURE			 1112
+#define SSL_R_BAD_ECPOINT				 1113
+#define SSL_R_BAD_HELLO_REQUEST				 105
+#define SSL_R_BAD_LENGTH				 271
+#define SSL_R_BAD_MAC_DECODE				 113
+#define SSL_R_BAD_MESSAGE_TYPE				 114
+#define SSL_R_BAD_PACKET_LENGTH				 115
+#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER		 116
+#define SSL_R_BAD_RESPONSE_ARGUMENT			 117
+#define SSL_R_BAD_RSA_DECRYPT				 118
+#define SSL_R_BAD_RSA_ENCRYPT				 119
+#define SSL_R_BAD_RSA_E_LENGTH				 120
+#define SSL_R_BAD_RSA_MODULUS_LENGTH			 121
+#define SSL_R_BAD_RSA_SIGNATURE				 122
+#define SSL_R_BAD_SIGNATURE				 123
+#define SSL_R_BAD_SSL_FILETYPE				 124
+#define SSL_R_BAD_SSL_SESSION_ID_LENGTH			 125
+#define SSL_R_BAD_STATE					 126
+#define SSL_R_BAD_WRITE_RETRY				 127
+#define SSL_R_BIO_NOT_SET				 128
+#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG			 129
+#define SSL_R_BN_LIB					 130
+#define SSL_R_CA_DN_LENGTH_MISMATCH			 131
+#define SSL_R_CA_DN_TOO_LONG				 132
+#define SSL_R_CCS_RECEIVED_EARLY			 133
+#define SSL_R_CERTIFICATE_VERIFY_FAILED			 134
+#define SSL_R_CERT_LENGTH_MISMATCH			 135
+#define SSL_R_CHALLENGE_IS_DIFFERENT			 136
+#define SSL_R_CIPHER_CODE_WRONG_LENGTH			 137
+#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE		 138
+#define SSL_R_CIPHER_TABLE_SRC_ERROR			 139
+#define SSL_R_COMPRESSED_LENGTH_TOO_LONG		 140
+#define SSL_R_COMPRESSION_FAILURE			 141
+#define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE	 1120
+#define SSL_R_COMPRESSION_LIBRARY_ERROR			 142
+#define SSL_R_CONNECTION_ID_IS_DIFFERENT		 143
+#define SSL_R_CONNECTION_TYPE_NOT_SET			 144
+#define SSL_R_COOKIE_MISMATCH				 2002
+#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED		 145
+#define SSL_R_DATA_LENGTH_TOO_LONG			 146
+#define SSL_R_DECRYPTION_FAILED				 147
+#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC	 1109
+#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG		 148
+#define SSL_R_DIGEST_CHECK_FAILED			 149
+#define SSL_R_DUPLICATE_COMPRESSION_ID			 1121
+#define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER		 1119
+#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG			 150
+#define SSL_R_ERROR_GENERATING_TMP_RSA_KEY		 1092
+#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST		 151
+#define SSL_R_EXCESSIVE_MESSAGE_SIZE			 152
+#define SSL_R_EXTRA_DATA_IN_MESSAGE			 153
+#define SSL_R_GOT_A_FIN_BEFORE_A_CCS			 154
+#define SSL_R_HTTPS_PROXY_REQUEST			 155
+#define SSL_R_HTTP_REQUEST				 156
+#define SSL_R_ILLEGAL_PADDING				 1110
+#define SSL_R_INVALID_CHALLENGE_LENGTH			 158
+#define SSL_R_INVALID_COMMAND				 280
+#define SSL_R_INVALID_PURPOSE				 278
+#define SSL_R_INVALID_TRUST				 279
+#define SSL_R_KEY_ARG_TOO_LONG				 1112
+#define SSL_R_KRB5					 1104
+#define SSL_R_KRB5_C_CC_PRINC				 1094
+#define SSL_R_KRB5_C_GET_CRED				 1095
+#define SSL_R_KRB5_C_INIT				 1096
+#define SSL_R_KRB5_C_MK_REQ				 1097
+#define SSL_R_KRB5_S_BAD_TICKET				 1098
+#define SSL_R_KRB5_S_INIT				 1099
+#define SSL_R_KRB5_S_RD_REQ				 1108
+#define SSL_R_KRB5_S_TKT_EXPIRED			 1105
+#define SSL_R_KRB5_S_TKT_NYV				 1106
+#define SSL_R_KRB5_S_TKT_SKEW				 1107
+#define SSL_R_LENGTH_MISMATCH				 159
+#define SSL_R_LENGTH_TOO_SHORT				 160
+#define SSL_R_LIBRARY_BUG				 274
+#define SSL_R_LIBRARY_HAS_NO_CIPHERS			 161
+#define SSL_R_MASTER_KEY_TOO_LONG			 1112
+#define SSL_R_MESSAGE_TOO_LONG				 1111
+#define SSL_R_MISSING_DH_DSA_CERT			 162
+#define SSL_R_MISSING_DH_KEY				 163
+#define SSL_R_MISSING_DH_RSA_CERT			 164
+#define SSL_R_MISSING_DSA_SIGNING_CERT			 165
+#define SSL_R_MISSING_EXPORT_TMP_DH_KEY			 166
+#define SSL_R_MISSING_EXPORT_TMP_RSA_KEY		 167
+#define SSL_R_MISSING_RSA_CERTIFICATE			 168
+#define SSL_R_MISSING_RSA_ENCRYPTING_CERT		 169
+#define SSL_R_MISSING_RSA_SIGNING_CERT			 170
+#define SSL_R_MISSING_TMP_DH_KEY			 171
+#define SSL_R_MISSING_TMP_ECDH_KEY			 1114
+#define SSL_R_MISSING_TMP_RSA_KEY			 172
+#define SSL_R_MISSING_TMP_RSA_PKEY			 173
+#define SSL_R_MISSING_VERIFY_MESSAGE			 174
+#define SSL_R_NON_SSLV2_INITIAL_PACKET			 175
+#define SSL_R_NO_CERTIFICATES_RETURNED			 176
+#define SSL_R_NO_CERTIFICATE_ASSIGNED			 177
+#define SSL_R_NO_CERTIFICATE_RETURNED			 178
+#define SSL_R_NO_CERTIFICATE_SET			 179
+#define SSL_R_NO_CERTIFICATE_SPECIFIED			 180
+#define SSL_R_NO_CIPHERS_AVAILABLE			 181
+#define SSL_R_NO_CIPHERS_PASSED				 182
+#define SSL_R_NO_CIPHERS_SPECIFIED			 183
+#define SSL_R_NO_CIPHER_LIST				 184
+#define SSL_R_NO_CIPHER_MATCH				 185
+#define SSL_R_NO_CLIENT_CERT_RECEIVED			 186
+#define SSL_R_NO_COMPRESSION_SPECIFIED			 187
+#define SSL_R_NO_METHOD_SPECIFIED			 188
+#define SSL_R_NO_PRIVATEKEY				 189
+#define SSL_R_NO_PRIVATE_KEY_ASSIGNED			 190
+#define SSL_R_NO_PROTOCOLS_AVAILABLE			 191
+#define SSL_R_NO_PUBLICKEY				 192
+#define SSL_R_NO_SHARED_CIPHER				 193
+#define SSL_R_NO_VERIFY_CALLBACK			 194
+#define SSL_R_NULL_SSL_CTX				 195
+#define SSL_R_NULL_SSL_METHOD_PASSED			 196
+#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED		 197
+#define SSL_R_PACKET_LENGTH_TOO_LONG			 198
+#define SSL_R_PATH_TOO_LONG				 270
+#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE		 199
+#define SSL_R_PEER_ERROR				 200
+#define SSL_R_PEER_ERROR_CERTIFICATE			 201
+#define SSL_R_PEER_ERROR_NO_CERTIFICATE			 202
+#define SSL_R_PEER_ERROR_NO_CIPHER			 203
+#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE	 204
+#define SSL_R_PRE_MAC_LENGTH_TOO_LONG			 205
+#define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS		 206
+#define SSL_R_PROTOCOL_IS_SHUTDOWN			 207
+#define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR			 208
+#define SSL_R_PUBLIC_KEY_IS_NOT_RSA			 209
+#define SSL_R_PUBLIC_KEY_NOT_RSA			 210
+#define SSL_R_READ_BIO_NOT_SET				 211
+#define SSL_R_READ_TIMEOUT_EXPIRED			 2001
+#define SSL_R_READ_WRONG_PACKET_TYPE			 212
+#define SSL_R_RECORD_LENGTH_MISMATCH			 213
+#define SSL_R_RECORD_TOO_LARGE				 214
+#define SSL_R_RECORD_TOO_SMALL				 1093
+#define SSL_R_REQUIRED_CIPHER_MISSING			 215
+#define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO		 216
+#define SSL_R_REUSE_CERT_TYPE_NOT_ZERO			 217
+#define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO		 218
+#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED		 277
+#define SSL_R_SHORT_READ				 219
+#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE	 220
+#define SSL_R_SSL23_DOING_SESSION_ID_REUSE		 221
+#define SSL_R_SSL2_CONNECTION_ID_TOO_LONG		 1114
+#define SSL_R_SSL3_SESSION_ID_TOO_LONG			 1113
+#define SSL_R_SSL3_SESSION_ID_TOO_SHORT			 222
+#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE		 1042
+#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC		 1020
+#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED		 1045
+#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED		 1044
+#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN		 1046
+#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE		 1030
+#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE		 1040
+#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER		 1047
+#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE		 1041
+#define SSL_R_SSLV3_ALERT_PEER_ERROR_CERTIFICATE	 223
+#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CERTIFICATE	 224
+#define SSL_R_SSLV3_ALERT_PEER_ERROR_NO_CIPHER		 225
+#define SSL_R_SSLV3_ALERT_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 226
+#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE		 1010
+#define SSL_R_SSLV3_ALERT_UNKNOWN_REMOTE_ERROR_TYPE	 227
+#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE	 1043
+#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION	 228
+#define SSL_R_SSL_HANDSHAKE_FAILURE			 229
+#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS		 230
+#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED		 1102
+#define SSL_R_SSL_SESSION_ID_CONFLICT			 1103
+#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG		 273
+#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH		 1101
+#define SSL_R_SSL_SESSION_ID_IS_DIFFERENT		 231
+#define SSL_R_TLSV1_ALERT_ACCESS_DENIED			 1049
+#define SSL_R_TLSV1_ALERT_DECODE_ERROR			 1050
+#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED		 1021
+#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR			 1051
+#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION		 1060
+#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY		 1071
+#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR		 1080
+#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION		 1100
+#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION		 1070
+#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW		 1022
+#define SSL_R_TLSV1_ALERT_UNKNOWN_CA			 1048
+#define SSL_R_TLSV1_ALERT_USER_CANCELLED		 1090
+#define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER	 232
+#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
+#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG	 234
+#define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER		 235
+#define SSL_R_UNABLE_TO_DECODE_DH_CERTS			 236
+#define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS		 1115
+#define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY		 237
+#define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS		 238
+#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS		 1116
+#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS	 239
+#define SSL_R_UNABLE_TO_FIND_SSL_METHOD			 240
+#define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES		 241
+#define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES		 242
+#define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES		 243
+#define SSL_R_UNEXPECTED_MESSAGE			 244
+#define SSL_R_UNEXPECTED_RECORD				 245
+#define SSL_R_UNINITIALIZED				 276
+#define SSL_R_UNKNOWN_ALERT_TYPE			 246
+#define SSL_R_UNKNOWN_CERTIFICATE_TYPE			 247
+#define SSL_R_UNKNOWN_CIPHER_RETURNED			 248
+#define SSL_R_UNKNOWN_CIPHER_TYPE			 249
+#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE			 250
+#define SSL_R_UNKNOWN_PKEY_TYPE				 251
+#define SSL_R_UNKNOWN_PROTOCOL				 252
+#define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE			 253
+#define SSL_R_UNKNOWN_SSL_VERSION			 254
+#define SSL_R_UNKNOWN_STATE				 255
+#define SSL_R_UNSUPPORTED_CIPHER			 256
+#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM		 257
+#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE		 1118
+#define SSL_R_UNSUPPORTED_OPTION			 1091
+#define SSL_R_UNSUPPORTED_PROTOCOL			 258
+#define SSL_R_UNSUPPORTED_SSL_VERSION			 259
+#define SSL_R_WRITE_BIO_NOT_SET				 260
+#define SSL_R_WRONG_CIPHER_RETURNED			 261
+#define SSL_R_WRONG_MESSAGE_TYPE			 262
+#define SSL_R_WRONG_NUMBER_OF_KEY_BITS			 263
+#define SSL_R_WRONG_SIGNATURE_LENGTH			 264
+#define SSL_R_WRONG_SIGNATURE_SIZE			 265
+#define SSL_R_WRONG_SSL_VERSION				 266
+#define SSL_R_WRONG_VERSION_NUMBER			 267
+#define SSL_R_X509_LIB					 268
+#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS		 269
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl2.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl2.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,268 @@
+/* ssl/ssl2.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL2_H 
+#define HEADER_SSL2_H 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Protocol Version Codes */
+#define SSL2_VERSION		0x0002
+#define SSL2_VERSION_MAJOR	0x00
+#define SSL2_VERSION_MINOR	0x02
+/* #define SSL2_CLIENT_VERSION	0x0002 */
+/* #define SSL2_SERVER_VERSION	0x0002 */
+
+/* Protocol Message Codes */
+#define SSL2_MT_ERROR			0
+#define SSL2_MT_CLIENT_HELLO		1
+#define SSL2_MT_CLIENT_MASTER_KEY	2
+#define SSL2_MT_CLIENT_FINISHED		3
+#define SSL2_MT_SERVER_HELLO		4
+#define SSL2_MT_SERVER_VERIFY		5
+#define SSL2_MT_SERVER_FINISHED		6
+#define SSL2_MT_REQUEST_CERTIFICATE	7
+#define SSL2_MT_CLIENT_CERTIFICATE	8
+
+/* Error Message Codes */
+#define SSL2_PE_UNDEFINED_ERROR		0x0000
+#define SSL2_PE_NO_CIPHER		0x0001
+#define SSL2_PE_NO_CERTIFICATE		0x0002
+#define SSL2_PE_BAD_CERTIFICATE		0x0004
+#define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
+
+/* Cipher Kind Values */
+#define SSL2_CK_NULL_WITH_MD5			0x02000000 /* v3 */
+#define SSL2_CK_RC4_128_WITH_MD5		0x02010080
+#define SSL2_CK_RC4_128_EXPORT40_WITH_MD5	0x02020080
+#define SSL2_CK_RC2_128_CBC_WITH_MD5		0x02030080
+#define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5	0x02040080
+#define SSL2_CK_IDEA_128_CBC_WITH_MD5		0x02050080
+#define SSL2_CK_DES_64_CBC_WITH_MD5		0x02060040
+#define SSL2_CK_DES_64_CBC_WITH_SHA		0x02060140 /* v3 */
+#define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5	0x020700c0
+#define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA	0x020701c0 /* v3 */
+#define SSL2_CK_RC4_64_WITH_MD5			0x02080080 /* MS hack */
+ 
+#define SSL2_CK_DES_64_CFB64_WITH_MD5_1		0x02ff0800 /* SSLeay */
+#define SSL2_CK_NULL				0x02ff0810 /* SSLeay */
+
+#define SSL2_TXT_DES_64_CFB64_WITH_MD5_1	"DES-CFB-M1"
+#define SSL2_TXT_NULL_WITH_MD5			"NULL-MD5"
+#define SSL2_TXT_RC4_128_WITH_MD5		"RC4-MD5"
+#define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5	"EXP-RC4-MD5"
+#define SSL2_TXT_RC2_128_CBC_WITH_MD5		"RC2-CBC-MD5"
+#define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5	"EXP-RC2-CBC-MD5"
+#define SSL2_TXT_IDEA_128_CBC_WITH_MD5		"IDEA-CBC-MD5"
+#define SSL2_TXT_DES_64_CBC_WITH_MD5		"DES-CBC-MD5"
+#define SSL2_TXT_DES_64_CBC_WITH_SHA		"DES-CBC-SHA"
+#define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5	"DES-CBC3-MD5"
+#define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA	"DES-CBC3-SHA"
+#define SSL2_TXT_RC4_64_WITH_MD5		"RC4-64-MD5"
+
+#define SSL2_TXT_NULL				"NULL"
+
+/* Flags for the SSL_CIPHER.algorithm2 field */
+#define SSL2_CF_5_BYTE_ENC			0x01
+#define SSL2_CF_8_BYTE_ENC			0x02
+
+/* Certificate Type Codes */
+#define SSL2_CT_X509_CERTIFICATE		0x01
+
+/* Authentication Type Code */
+#define SSL2_AT_MD5_WITH_RSA_ENCRYPTION		0x01
+
+#define SSL2_MAX_SSL_SESSION_ID_LENGTH		32
+
+/* Upper/Lower Bounds */
+#define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS	256
+#ifdef OPENSSL_SYS_MPE
+#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER	29998u
+#else
+#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER	32767u  /* 2^15-1 */
+#endif
+#define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER	16383 /* 2^14-1 */
+
+#define SSL2_CHALLENGE_LENGTH	16
+/*#define SSL2_CHALLENGE_LENGTH	32 */
+#define SSL2_MIN_CHALLENGE_LENGTH	16
+#define SSL2_MAX_CHALLENGE_LENGTH	32
+#define SSL2_CONNECTION_ID_LENGTH	16
+#define SSL2_MAX_CONNECTION_ID_LENGTH	16
+#define SSL2_SSL_SESSION_ID_LENGTH	16
+#define SSL2_MAX_CERT_CHALLENGE_LENGTH	32
+#define SSL2_MIN_CERT_CHALLENGE_LENGTH	16
+#define SSL2_MAX_KEY_MATERIAL_LENGTH	24
+
+#ifndef HEADER_SSL_LOCL_H
+#define  CERT		char
+#endif
+
+typedef struct ssl2_state_st
+	{
+	int three_byte_header;
+	int clear_text;		/* clear text */
+	int escape;		/* not used in SSLv2 */
+	int ssl2_rollback;	/* used if SSLv23 rolled back to SSLv2 */
+
+	/* non-blocking io info, used to make sure the same
+	 * args were passwd */
+	unsigned int wnum;	/* number of bytes sent so far */
+	int wpend_tot;
+	const unsigned char *wpend_buf;
+
+	int wpend_off;	/* offset to data to write */
+	int wpend_len; 	/* number of bytes passwd to write */
+	int wpend_ret; 	/* number of bytes to return to caller */
+
+	/* buffer raw data */
+	int rbuf_left;
+	int rbuf_offs;
+	unsigned char *rbuf;
+	unsigned char *wbuf;
+
+	unsigned char *write_ptr;/* used to point to the start due to
+				  * 2/3 byte header. */
+
+	unsigned int padding;
+	unsigned int rlength; /* passed to ssl2_enc */
+	int ract_data_length; /* Set when things are encrypted. */
+	unsigned int wlength; /* passed to ssl2_enc */
+	int wact_data_length; /* Set when things are decrypted. */
+	unsigned char *ract_data;
+	unsigned char *wact_data;
+	unsigned char *mac_data;
+
+	unsigned char *read_key;
+	unsigned char *write_key;
+
+		/* Stuff specifically to do with this SSL session */
+	unsigned int challenge_length;
+	unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH];
+	unsigned int conn_id_length;
+	unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
+	unsigned int key_material_length;
+	unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH*2];
+
+	unsigned long read_sequence;
+	unsigned long write_sequence;
+
+	struct	{
+		unsigned int conn_id_length;
+		unsigned int cert_type;	
+		unsigned int cert_length;
+		unsigned int csl; 
+		unsigned int clear;
+		unsigned int enc; 
+		unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH];
+		unsigned int cipher_spec_length;
+		unsigned int session_id_length;
+		unsigned int clen;
+		unsigned int rlen;
+		} tmp;
+	} SSL2_STATE;
+
+/* SSLv2 */
+/* client */
+#define SSL2_ST_SEND_CLIENT_HELLO_A		(0x10|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_HELLO_B		(0x11|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_HELLO_A		(0x20|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_HELLO_B		(0x21|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_MASTER_KEY_A	(0x30|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_MASTER_KEY_B	(0x31|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_FINISHED_A		(0x40|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_FINISHED_B		(0x41|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_A	(0x50|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_B	(0x51|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_C	(0x52|SSL_ST_CONNECT)
+#define SSL2_ST_SEND_CLIENT_CERTIFICATE_D	(0x53|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_VERIFY_A		(0x60|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_VERIFY_B		(0x61|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_FINISHED_A		(0x70|SSL_ST_CONNECT)
+#define SSL2_ST_GET_SERVER_FINISHED_B		(0x71|SSL_ST_CONNECT)
+#define SSL2_ST_CLIENT_START_ENCRYPTION		(0x80|SSL_ST_CONNECT)
+#define SSL2_ST_X509_GET_CLIENT_CERTIFICATE	(0x90|SSL_ST_CONNECT)
+/* server */
+#define SSL2_ST_GET_CLIENT_HELLO_A		(0x10|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_HELLO_B		(0x11|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_HELLO_C		(0x12|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_HELLO_A		(0x20|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_HELLO_B		(0x21|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_MASTER_KEY_A		(0x30|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_MASTER_KEY_B		(0x31|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_VERIFY_A		(0x40|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_VERIFY_B		(0x41|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_VERIFY_C		(0x42|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_FINISHED_A		(0x50|SSL_ST_ACCEPT)
+#define SSL2_ST_GET_CLIENT_FINISHED_B		(0x51|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_FINISHED_A		(0x60|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_SERVER_FINISHED_B		(0x61|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_A	(0x70|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_B	(0x71|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_C	(0x72|SSL_ST_ACCEPT)
+#define SSL2_ST_SEND_REQUEST_CERTIFICATE_D	(0x73|SSL_ST_ACCEPT)
+#define SSL2_ST_SERVER_START_ENCRYPTION		(0x80|SSL_ST_ACCEPT)
+#define SSL2_ST_X509_GET_SERVER_CERTIFICATE	(0x90|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl23.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl23.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl23.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,83 @@
+/* ssl/ssl23.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_SSL23_H 
+#define HEADER_SSL23_H 
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*client */
+/* write to server */
+#define SSL23_ST_CW_CLNT_HELLO_A	(0x210|SSL_ST_CONNECT)
+#define SSL23_ST_CW_CLNT_HELLO_B	(0x211|SSL_ST_CONNECT)
+/* read from server */
+#define SSL23_ST_CR_SRVR_HELLO_A	(0x220|SSL_ST_CONNECT)
+#define SSL23_ST_CR_SRVR_HELLO_B	(0x221|SSL_ST_CONNECT)
+
+/* server */
+/* read from client */
+#define SSL23_ST_SR_CLNT_HELLO_A	(0x210|SSL_ST_ACCEPT)
+#define SSL23_ST_SR_CLNT_HELLO_B	(0x211|SSL_ST_ACCEPT)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl3.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl3.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ssl3.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,551 @@
+/* ssl/ssl3.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECC cipher suite support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_SSL3_H 
+#define HEADER_SSL3_H 
+
+#ifndef OPENSSL_NO_COMP
+#include <openssl/comp.h>
+#endif
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/ssl.h>
+#include <openssl/pq_compat.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define SSL3_CK_RSA_NULL_MD5			0x03000001
+#define SSL3_CK_RSA_NULL_SHA			0x03000002
+#define SSL3_CK_RSA_RC4_40_MD5 			0x03000003
+#define SSL3_CK_RSA_RC4_128_MD5			0x03000004
+#define SSL3_CK_RSA_RC4_128_SHA			0x03000005
+#define SSL3_CK_RSA_RC2_40_MD5			0x03000006
+#define SSL3_CK_RSA_IDEA_128_SHA		0x03000007
+#define SSL3_CK_RSA_DES_40_CBC_SHA		0x03000008
+#define SSL3_CK_RSA_DES_64_CBC_SHA		0x03000009
+#define SSL3_CK_RSA_DES_192_CBC3_SHA		0x0300000A
+
+#define SSL3_CK_DH_DSS_DES_40_CBC_SHA		0x0300000B
+#define SSL3_CK_DH_DSS_DES_64_CBC_SHA		0x0300000C
+#define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 	0x0300000D
+#define SSL3_CK_DH_RSA_DES_40_CBC_SHA		0x0300000E
+#define SSL3_CK_DH_RSA_DES_64_CBC_SHA		0x0300000F
+#define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 	0x03000010
+
+#define SSL3_CK_EDH_DSS_DES_40_CBC_SHA		0x03000011
+#define SSL3_CK_EDH_DSS_DES_64_CBC_SHA		0x03000012
+#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA	0x03000013
+#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA		0x03000014
+#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA		0x03000015
+#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA	0x03000016
+
+#define SSL3_CK_ADH_RC4_40_MD5			0x03000017
+#define SSL3_CK_ADH_RC4_128_MD5			0x03000018
+#define SSL3_CK_ADH_DES_40_CBC_SHA		0x03000019
+#define SSL3_CK_ADH_DES_64_CBC_SHA		0x0300001A
+#define SSL3_CK_ADH_DES_192_CBC_SHA		0x0300001B
+
+#define SSL3_CK_FZA_DMS_NULL_SHA		0x0300001C
+#define SSL3_CK_FZA_DMS_FZA_SHA			0x0300001D
+#if 0 /* Because it clashes with KRB5, is never used any more, and is safe
+	 to remove according to David Hopwood <david.hopwood@zetnet.co.uk>
+	 of the ietf-tls list */
+#define SSL3_CK_FZA_DMS_RC4_SHA			0x0300001E
+#endif
+
+/*    VRS Additional Kerberos5 entries
+ */
+#define SSL3_CK_KRB5_DES_64_CBC_SHA		0x0300001E
+#define SSL3_CK_KRB5_DES_192_CBC3_SHA		0x0300001F
+#define SSL3_CK_KRB5_RC4_128_SHA		0x03000020
+#define SSL3_CK_KRB5_IDEA_128_CBC_SHA	       	0x03000021
+#define SSL3_CK_KRB5_DES_64_CBC_MD5       	0x03000022
+#define SSL3_CK_KRB5_DES_192_CBC3_MD5       	0x03000023
+#define SSL3_CK_KRB5_RC4_128_MD5	       	0x03000024
+#define SSL3_CK_KRB5_IDEA_128_CBC_MD5 		0x03000025
+
+#define SSL3_CK_KRB5_DES_40_CBC_SHA 		0x03000026
+#define SSL3_CK_KRB5_RC2_40_CBC_SHA 		0x03000027
+#define SSL3_CK_KRB5_RC4_40_SHA	 		0x03000028
+#define SSL3_CK_KRB5_DES_40_CBC_MD5 		0x03000029
+#define SSL3_CK_KRB5_RC2_40_CBC_MD5 		0x0300002A
+#define SSL3_CK_KRB5_RC4_40_MD5	 		0x0300002B
+
+#define SSL3_TXT_RSA_NULL_MD5			"NULL-MD5"
+#define SSL3_TXT_RSA_NULL_SHA			"NULL-SHA"
+#define SSL3_TXT_RSA_RC4_40_MD5 		"EXP-RC4-MD5"
+#define SSL3_TXT_RSA_RC4_128_MD5		"RC4-MD5"
+#define SSL3_TXT_RSA_RC4_128_SHA		"RC4-SHA"
+#define SSL3_TXT_RSA_RC2_40_MD5			"EXP-RC2-CBC-MD5"
+#define SSL3_TXT_RSA_IDEA_128_SHA		"IDEA-CBC-SHA"
+#define SSL3_TXT_RSA_DES_40_CBC_SHA		"EXP-DES-CBC-SHA"
+#define SSL3_TXT_RSA_DES_64_CBC_SHA		"DES-CBC-SHA"
+#define SSL3_TXT_RSA_DES_192_CBC3_SHA		"DES-CBC3-SHA"
+
+#define SSL3_TXT_DH_DSS_DES_40_CBC_SHA		"EXP-DH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_DH_DSS_DES_64_CBC_SHA		"DH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA 	"DH-DSS-DES-CBC3-SHA"
+#define SSL3_TXT_DH_RSA_DES_40_CBC_SHA		"EXP-DH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_DH_RSA_DES_64_CBC_SHA		"DH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA 	"DH-RSA-DES-CBC3-SHA"
+
+#define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA		"EXP-EDH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA		"EDH-DSS-DES-CBC-SHA"
+#define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA	"EDH-DSS-DES-CBC3-SHA"
+#define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA		"EXP-EDH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA		"EDH-RSA-DES-CBC-SHA"
+#define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA	"EDH-RSA-DES-CBC3-SHA"
+
+#define SSL3_TXT_ADH_RC4_40_MD5			"EXP-ADH-RC4-MD5"
+#define SSL3_TXT_ADH_RC4_128_MD5		"ADH-RC4-MD5"
+#define SSL3_TXT_ADH_DES_40_CBC_SHA		"EXP-ADH-DES-CBC-SHA"
+#define SSL3_TXT_ADH_DES_64_CBC_SHA		"ADH-DES-CBC-SHA"
+#define SSL3_TXT_ADH_DES_192_CBC_SHA		"ADH-DES-CBC3-SHA"
+
+#define SSL3_TXT_FZA_DMS_NULL_SHA		"FZA-NULL-SHA"
+#define SSL3_TXT_FZA_DMS_FZA_SHA		"FZA-FZA-CBC-SHA"
+#define SSL3_TXT_FZA_DMS_RC4_SHA		"FZA-RC4-SHA"
+
+#define SSL3_TXT_KRB5_DES_64_CBC_SHA		"KRB5-DES-CBC-SHA"
+#define SSL3_TXT_KRB5_DES_192_CBC3_SHA		"KRB5-DES-CBC3-SHA"
+#define SSL3_TXT_KRB5_RC4_128_SHA		"KRB5-RC4-SHA"
+#define SSL3_TXT_KRB5_IDEA_128_CBC_SHA	       	"KRB5-IDEA-CBC-SHA"
+#define SSL3_TXT_KRB5_DES_64_CBC_MD5       	"KRB5-DES-CBC-MD5"
+#define SSL3_TXT_KRB5_DES_192_CBC3_MD5       	"KRB5-DES-CBC3-MD5"
+#define SSL3_TXT_KRB5_RC4_128_MD5		"KRB5-RC4-MD5"
+#define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 		"KRB5-IDEA-CBC-MD5"
+
+#define SSL3_TXT_KRB5_DES_40_CBC_SHA 		"EXP-KRB5-DES-CBC-SHA"
+#define SSL3_TXT_KRB5_RC2_40_CBC_SHA 		"EXP-KRB5-RC2-CBC-SHA"
+#define SSL3_TXT_KRB5_RC4_40_SHA	 	"EXP-KRB5-RC4-SHA"
+#define SSL3_TXT_KRB5_DES_40_CBC_MD5 		"EXP-KRB5-DES-CBC-MD5"
+#define SSL3_TXT_KRB5_RC2_40_CBC_MD5 		"EXP-KRB5-RC2-CBC-MD5"
+#define SSL3_TXT_KRB5_RC4_40_MD5	 	"EXP-KRB5-RC4-MD5"
+
+#define SSL3_SSL_SESSION_ID_LENGTH		32
+#define SSL3_MAX_SSL_SESSION_ID_LENGTH		32
+
+#define SSL3_MASTER_SECRET_SIZE			48
+#define SSL3_RANDOM_SIZE			32
+#define SSL3_SESSION_ID_SIZE			32
+#define SSL3_RT_HEADER_LENGTH			5
+
+/* Due to MS stuffing up, this can change.... */
+#if defined(OPENSSL_SYS_WIN16) || \
+	(defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32))
+#define SSL3_RT_MAX_EXTRA			(14000)
+#else
+#define SSL3_RT_MAX_EXTRA			(16384)
+#endif
+
+#define SSL3_RT_MAX_PLAIN_LENGTH		16384
+#define SSL3_RT_MAX_COMPRESSED_LENGTH	(1024+SSL3_RT_MAX_PLAIN_LENGTH)
+#define SSL3_RT_MAX_ENCRYPTED_LENGTH	(1024+SSL3_RT_MAX_COMPRESSED_LENGTH)
+#define SSL3_RT_MAX_PACKET_SIZE		(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)
+#define SSL3_RT_MAX_DATA_SIZE			(1024*1024)
+
+#define SSL3_MD_CLIENT_FINISHED_CONST	"\x43\x4C\x4E\x54"
+#define SSL3_MD_SERVER_FINISHED_CONST	"\x53\x52\x56\x52"
+
+#define SSL3_VERSION			0x0300
+#define SSL3_VERSION_MAJOR		0x03
+#define SSL3_VERSION_MINOR		0x00
+
+#define SSL3_RT_CHANGE_CIPHER_SPEC	20
+#define SSL3_RT_ALERT			21
+#define SSL3_RT_HANDSHAKE		22
+#define SSL3_RT_APPLICATION_DATA	23
+
+#define SSL3_AL_WARNING			1
+#define SSL3_AL_FATAL			2
+
+#define SSL3_AD_CLOSE_NOTIFY		 0
+#define SSL3_AD_UNEXPECTED_MESSAGE	10	/* fatal */
+#define SSL3_AD_BAD_RECORD_MAC		20	/* fatal */
+#define SSL3_AD_DECOMPRESSION_FAILURE	30	/* fatal */
+#define SSL3_AD_HANDSHAKE_FAILURE	40	/* fatal */
+#define SSL3_AD_NO_CERTIFICATE		41
+#define SSL3_AD_BAD_CERTIFICATE		42
+#define SSL3_AD_UNSUPPORTED_CERTIFICATE	43
+#define SSL3_AD_CERTIFICATE_REVOKED	44
+#define SSL3_AD_CERTIFICATE_EXPIRED	45
+#define SSL3_AD_CERTIFICATE_UNKNOWN	46
+#define SSL3_AD_ILLEGAL_PARAMETER	47	/* fatal */
+
+typedef struct ssl3_record_st
+	{
+/*r */	int type;               /* type of record */
+/*rw*/	unsigned int length;    /* How many bytes available */
+/*r */	unsigned int off;       /* read/write offset into 'buf' */
+/*rw*/	unsigned char *data;    /* pointer to the record data */
+/*rw*/	unsigned char *input;   /* where the decode bytes are */
+/*r */	unsigned char *comp;    /* only used with decompression - malloc()ed */
+/*r */  unsigned long epoch;    /* epoch number, needed by DTLS1 */
+/*r */  PQ_64BIT seq_num;       /* sequence number, needed by DTLS1 */
+	} SSL3_RECORD;
+
+typedef struct ssl3_buffer_st
+	{
+	unsigned char *buf;     /* at least SSL3_RT_MAX_PACKET_SIZE bytes,
+	                         * see ssl3_setup_buffers() */
+	size_t len;             /* buffer size */
+	int offset;             /* where to 'copy from' */
+	int left;               /* how many bytes left */
+	} SSL3_BUFFER;
+
+#define SSL3_CT_RSA_SIGN			1
+#define SSL3_CT_DSS_SIGN			2
+#define SSL3_CT_RSA_FIXED_DH			3
+#define SSL3_CT_DSS_FIXED_DH			4
+#define SSL3_CT_RSA_EPHEMERAL_DH		5
+#define SSL3_CT_DSS_EPHEMERAL_DH		6
+#define SSL3_CT_FORTEZZA_DMS			20
+/* SSL3_CT_NUMBER is used to size arrays and it must be large
+ * enough to contain all of the cert types defined either for
+ * SSLv3 and TLSv1.
+ */
+#define SSL3_CT_NUMBER			7
+
+
+#define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS	0x0001
+#define SSL3_FLAGS_DELAY_CLIENT_FINISHED	0x0002
+#define SSL3_FLAGS_POP_BUFFER			0x0004
+#define TLS1_FLAGS_TLS_PADDING_BUG		0x0008
+
+typedef struct ssl3_state_st
+	{
+	long flags;
+	int delay_buf_pop_ret;
+
+	unsigned char read_sequence[8];
+	unsigned char read_mac_secret[EVP_MAX_MD_SIZE];
+	unsigned char write_sequence[8];
+	unsigned char write_mac_secret[EVP_MAX_MD_SIZE];
+
+	unsigned char server_random[SSL3_RANDOM_SIZE];
+	unsigned char client_random[SSL3_RANDOM_SIZE];
+
+	/* flags for countermeasure against known-IV weakness */
+	int need_empty_fragments;
+	int empty_fragment_done;
+
+	SSL3_BUFFER rbuf;	/* read IO goes into here */
+	SSL3_BUFFER wbuf;	/* write IO goes into here */
+
+	SSL3_RECORD rrec;	/* each decoded record goes in here */
+	SSL3_RECORD wrec;	/* goes out from here */
+
+	/* storage for Alert/Handshake protocol data received but not
+	 * yet processed by ssl3_read_bytes: */
+	unsigned char alert_fragment[2];
+	unsigned int alert_fragment_len;
+	unsigned char handshake_fragment[4];
+	unsigned int handshake_fragment_len;
+
+	/* partial write - check the numbers match */
+	unsigned int wnum;	/* number of bytes sent so far */
+	int wpend_tot;		/* number bytes written */
+	int wpend_type;
+	int wpend_ret;		/* number of bytes submitted */
+	const unsigned char *wpend_buf;
+
+	/* used during startup, digest all incoming/outgoing packets */
+	EVP_MD_CTX finish_dgst1;
+	EVP_MD_CTX finish_dgst2;
+
+	/* this is set whenerver we see a change_cipher_spec message
+	 * come in when we are not looking for one */
+	int change_cipher_spec;
+
+	int warn_alert;
+	int fatal_alert;
+	/* we allow one fatal and one warning alert to be outstanding,
+	 * send close alert via the warning alert */
+	int alert_dispatch;
+	unsigned char send_alert[2];
+
+	/* This flag is set when we should renegotiate ASAP, basically when
+	 * there is no more data in the read or write buffers */
+	int renegotiate;
+	int total_renegotiations;
+	int num_renegotiations;
+
+	int in_read_app_data;
+
+	struct	{
+		/* actually only needs to be 16+20 */
+		unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];
+
+		/* actually only need to be 16+20 for SSLv3 and 12 for TLS */
+		unsigned char finish_md[EVP_MAX_MD_SIZE*2];
+		int finish_md_len;
+		unsigned char peer_finish_md[EVP_MAX_MD_SIZE*2];
+		int peer_finish_md_len;
+		
+		unsigned long message_size;
+		int message_type;
+
+		/* used to hold the new cipher we are going to use */
+		SSL_CIPHER *new_cipher;
+#ifndef OPENSSL_NO_DH
+		DH *dh;
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+		EC_KEY *ecdh; /* holds short lived ECDH key */
+#endif
+
+		/* used when SSL_ST_FLUSH_DATA is entered */
+		int next_state;			
+
+		int reuse_message;
+
+		/* used for certificate requests */
+		int cert_req;
+		int ctype_num;
+		char ctype[SSL3_CT_NUMBER];
+		STACK_OF(X509_NAME) *ca_names;
+
+		int use_rsa_tmp;
+
+		int key_block_length;
+		unsigned char *key_block;
+
+		const EVP_CIPHER *new_sym_enc;
+		const EVP_MD *new_hash;
+#ifndef OPENSSL_NO_COMP
+		const SSL_COMP *new_compression;
+#else
+		char *new_compression;
+#endif
+		int cert_request;
+		} tmp;
+
+	} SSL3_STATE;
+
+
+/* SSLv3 */
+/*client */
+/* extra state */
+#define SSL3_ST_CW_FLUSH		(0x100|SSL_ST_CONNECT)
+/* write to server */
+#define SSL3_ST_CW_CLNT_HELLO_A		(0x110|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CLNT_HELLO_B		(0x111|SSL_ST_CONNECT)
+/* read from server */
+#define SSL3_ST_CR_SRVR_HELLO_A		(0x120|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SRVR_HELLO_B		(0x121|SSL_ST_CONNECT)
+#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT)
+#define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_A		(0x130|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_B		(0x131|SSL_ST_CONNECT)
+#define SSL3_ST_CR_KEY_EXCH_A		(0x140|SSL_ST_CONNECT)
+#define SSL3_ST_CR_KEY_EXCH_B		(0x141|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_REQ_A		(0x150|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CERT_REQ_B		(0x151|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SRVR_DONE_A		(0x160|SSL_ST_CONNECT)
+#define SSL3_ST_CR_SRVR_DONE_B		(0x161|SSL_ST_CONNECT)
+/* write to server */
+#define SSL3_ST_CW_CERT_A		(0x170|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_B		(0x171|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_C		(0x172|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_D		(0x173|SSL_ST_CONNECT)
+#define SSL3_ST_CW_KEY_EXCH_A		(0x180|SSL_ST_CONNECT)
+#define SSL3_ST_CW_KEY_EXCH_B		(0x181|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_VRFY_A		(0x190|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_VRFY_B		(0x191|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CHANGE_A		(0x1A0|SSL_ST_CONNECT)
+#define SSL3_ST_CW_CHANGE_B		(0x1A1|SSL_ST_CONNECT)
+#define SSL3_ST_CW_FINISHED_A		(0x1B0|SSL_ST_CONNECT)
+#define SSL3_ST_CW_FINISHED_B		(0x1B1|SSL_ST_CONNECT)
+/* read from server */
+#define SSL3_ST_CR_CHANGE_A		(0x1C0|SSL_ST_CONNECT)
+#define SSL3_ST_CR_CHANGE_B		(0x1C1|SSL_ST_CONNECT)
+#define SSL3_ST_CR_FINISHED_A		(0x1D0|SSL_ST_CONNECT)
+#define SSL3_ST_CR_FINISHED_B		(0x1D1|SSL_ST_CONNECT)
+
+/* server */
+/* extra state */
+#define SSL3_ST_SW_FLUSH		(0x100|SSL_ST_ACCEPT)
+/* read from client */
+/* Do not change the number values, they do matter */
+#define SSL3_ST_SR_CLNT_HELLO_A		(0x110|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CLNT_HELLO_B		(0x111|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CLNT_HELLO_C		(0x112|SSL_ST_ACCEPT)
+/* write to client */
+#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT)
+#define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_HELLO_REQ_A		(0x120|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_HELLO_REQ_B		(0x121|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_HELLO_REQ_C		(0x122|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_HELLO_A		(0x130|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_HELLO_B		(0x131|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_A		(0x140|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_B		(0x141|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_KEY_EXCH_A		(0x150|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_KEY_EXCH_B		(0x151|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_REQ_A		(0x160|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CERT_REQ_B		(0x161|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_DONE_A		(0x170|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_SRVR_DONE_B		(0x171|SSL_ST_ACCEPT)
+/* read from client */
+#define SSL3_ST_SR_CERT_A		(0x180|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CERT_B		(0x181|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_KEY_EXCH_A		(0x190|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_KEY_EXCH_B		(0x191|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CERT_VRFY_A		(0x1A0|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CERT_VRFY_B		(0x1A1|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CHANGE_A		(0x1B0|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_CHANGE_B		(0x1B1|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_FINISHED_A		(0x1C0|SSL_ST_ACCEPT)
+#define SSL3_ST_SR_FINISHED_B		(0x1C1|SSL_ST_ACCEPT)
+/* write to client */
+#define SSL3_ST_SW_CHANGE_A		(0x1D0|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_CHANGE_B		(0x1D1|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_FINISHED_A		(0x1E0|SSL_ST_ACCEPT)
+#define SSL3_ST_SW_FINISHED_B		(0x1E1|SSL_ST_ACCEPT)
+
+#define SSL3_MT_HELLO_REQUEST			0
+#define SSL3_MT_CLIENT_HELLO			1
+#define SSL3_MT_SERVER_HELLO			2
+#define SSL3_MT_CERTIFICATE			11
+#define SSL3_MT_SERVER_KEY_EXCHANGE		12
+#define SSL3_MT_CERTIFICATE_REQUEST		13
+#define SSL3_MT_SERVER_DONE			14
+#define SSL3_MT_CERTIFICATE_VERIFY		15
+#define SSL3_MT_CLIENT_KEY_EXCHANGE		16
+#define SSL3_MT_FINISHED			20
+#define DTLS1_MT_HELLO_VERIFY_REQUEST    3
+
+
+#define SSL3_MT_CCS				1
+
+/* These are used when changing over to a new cipher */
+#define SSL3_CC_READ		0x01
+#define SSL3_CC_WRITE		0x02
+#define SSL3_CC_CLIENT		0x10
+#define SSL3_CC_SERVER		0x20
+#define SSL3_CHANGE_CIPHER_CLIENT_WRITE	(SSL3_CC_CLIENT|SSL3_CC_WRITE)	
+#define SSL3_CHANGE_CIPHER_SERVER_READ	(SSL3_CC_SERVER|SSL3_CC_READ)
+#define SSL3_CHANGE_CIPHER_CLIENT_READ	(SSL3_CC_CLIENT|SSL3_CC_READ)
+#define SSL3_CHANGE_CIPHER_SERVER_WRITE	(SSL3_CC_SERVER|SSL3_CC_WRITE)
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/stack.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/stack.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/stack.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,109 @@
+/* crypto/stack/stack.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_STACK_H
+#define HEADER_STACK_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct stack_st
+	{
+	int num;
+	char **data;
+	int sorted;
+
+	int num_alloc;
+	int (*comp)(const char * const *, const char * const *);
+	} STACK;
+
+#define M_sk_num(sk)		((sk) ? (sk)->num:-1)
+#define M_sk_value(sk,n)	((sk) ? (sk)->data[n] : NULL)
+
+int sk_num(const STACK *);
+char *sk_value(const STACK *, int);
+
+char *sk_set(STACK *, int, char *);
+
+STACK *sk_new(int (*cmp)(const char * const *, const char * const *));
+STACK *sk_new_null(void);
+void sk_free(STACK *);
+void sk_pop_free(STACK *st, void (*func)(void *));
+int sk_insert(STACK *sk,char *data,int where);
+char *sk_delete(STACK *st,int loc);
+char *sk_delete_ptr(STACK *st, char *p);
+int sk_find(STACK *st,char *data);
+int sk_find_ex(STACK *st,char *data);
+int sk_push(STACK *st,char *data);
+int sk_unshift(STACK *st,char *data);
+char *sk_shift(STACK *st);
+char *sk_pop(STACK *st);
+void sk_zero(STACK *st);
+int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,
+			const char * const *)))
+			(const char * const *, const char * const *);
+STACK *sk_dup(STACK *st);
+void sk_sort(STACK *st);
+int sk_is_sorted(const STACK *st);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/store.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/store.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/store.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,554 @@
+/* crypto/store/store.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2003.
+ */
+/* ====================================================================
+ * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_STORE_H
+#define HEADER_STORE_H
+
+#include <openssl/ossl_typ.h>
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/x509.h>
+#endif
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Already defined in ossl_typ.h */
+/* typedef struct store_st STORE; */
+/* typedef struct store_method_st STORE_METHOD; */
+
+
+/* All the following functions return 0, a negative number or NULL on error.
+   When everything is fine, they return a positive value or a non-NULL
+   pointer, all depending on their purpose. */
+
+/* Creators and destructor.   */
+STORE *STORE_new_method(const STORE_METHOD *method);
+STORE *STORE_new_engine(ENGINE *engine);
+void STORE_free(STORE *ui);
+
+
+/* Give a user interface parametrised control commands.  This can be used to
+   send down an integer, a data pointer or a function pointer, as well as
+   be used to get information from a STORE. */
+int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f)(void));
+
+/* A control to set the directory with keys and certificates.  Used by the
+   built-in directory level method. */
+#define STORE_CTRL_SET_DIRECTORY	0x0001
+/* A control to set a file to load.  Used by the built-in file level method. */
+#define STORE_CTRL_SET_FILE		0x0002
+/* A control to set a configuration file to load.  Can be used by any method
+   that wishes to load a configuration file. */
+#define STORE_CTRL_SET_CONF_FILE	0x0003
+/* A control to set a the section of the loaded configuration file.  Can be
+   used by any method that wishes to load a configuration file. */
+#define STORE_CTRL_SET_CONF_SECTION	0x0004
+
+
+/* Some methods may use extra data */
+#define STORE_set_app_data(s,arg)	STORE_set_ex_data(s,0,arg)
+#define STORE_get_app_data(s)		STORE_get_ex_data(s,0)
+int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int STORE_set_ex_data(STORE *r,int idx,void *arg);
+void *STORE_get_ex_data(STORE *r, int idx);
+
+/* Use specific methods instead of the built-in one */
+const STORE_METHOD *STORE_get_method(STORE *store);
+const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth);
+
+/* The standard OpenSSL methods. */
+/* This is the in-memory method.  It does everything except revoking and updating,
+   and is of course volatile.  It's used by other methods that have an in-memory
+   cache. */
+const STORE_METHOD *STORE_Memory(void);
+#if 0 /* Not yet implemented */
+/* This is the directory store.  It does everything except revoking and updating,
+   and uses STORE_Memory() to cache things in memory. */
+const STORE_METHOD *STORE_Directory(void);
+/* This is the file store.  It does everything except revoking and updating,
+   and uses STORE_Memory() to cache things in memory.  Certificates are added
+   to it with the store operation, and it will only get cached certificates. */
+const STORE_METHOD *STORE_File(void);
+#endif
+
+/* Store functions take a type code for the type of data they should store
+   or fetch */
+typedef enum STORE_object_types
+	{
+	STORE_OBJECT_TYPE_X509_CERTIFICATE=	0x01, /* X509 * */
+	STORE_OBJECT_TYPE_X509_CRL=		0x02, /* X509_CRL * */
+	STORE_OBJECT_TYPE_PRIVATE_KEY=		0x03, /* EVP_PKEY * */
+	STORE_OBJECT_TYPE_PUBLIC_KEY=		0x04, /* EVP_PKEY * */
+	STORE_OBJECT_TYPE_NUMBER=		0x05, /* BIGNUM * */
+	STORE_OBJECT_TYPE_ARBITRARY=		0x06, /* BUF_MEM * */
+	STORE_OBJECT_TYPE_NUM=			0x06  /* The amount of known
+							 object types */
+	} STORE_OBJECT_TYPES;
+/* List of text strings corresponding to the object types. */
+extern const char * const STORE_object_type_string[STORE_OBJECT_TYPE_NUM+1];
+
+/* Some store functions take a parameter list.  Those parameters come with
+   one of the following codes. The comments following the codes below indicate
+   what type the value should be a pointer to. */
+typedef enum STORE_params
+	{
+	STORE_PARAM_EVP_TYPE=			0x01, /* int */
+	STORE_PARAM_BITS=			0x02, /* size_t */
+	STORE_PARAM_KEY_PARAMETERS=		0x03, /* ??? */
+	STORE_PARAM_KEY_NO_PARAMETERS=		0x04, /* N/A */
+	STORE_PARAM_AUTH_PASSPHRASE=		0x05, /* char * */
+	STORE_PARAM_AUTH_KRB5_TICKET=		0x06, /* void * */
+	STORE_PARAM_TYPE_NUM=			0x06  /* The amount of known
+							 parameter types */
+	} STORE_PARAM_TYPES;
+/* Parameter value sizes.  -1 means unknown, anything else is the required size. */
+extern const int STORE_param_sizes[STORE_PARAM_TYPE_NUM+1];
+
+/* Store functions take attribute lists.  Those attributes come with codes.
+   The comments following the codes below indicate what type the value should
+   be a pointer to. */
+typedef enum STORE_attribs
+	{
+	STORE_ATTR_END=				0x00,
+	STORE_ATTR_FRIENDLYNAME=		0x01, /* C string */
+	STORE_ATTR_KEYID=			0x02, /* 160 bit string (SHA1) */
+	STORE_ATTR_ISSUERKEYID=			0x03, /* 160 bit string (SHA1) */
+	STORE_ATTR_SUBJECTKEYID=		0x04, /* 160 bit string (SHA1) */
+	STORE_ATTR_ISSUERSERIALHASH=		0x05, /* 160 bit string (SHA1) */
+	STORE_ATTR_ISSUER=			0x06, /* X509_NAME * */
+	STORE_ATTR_SERIAL=			0x07, /* BIGNUM * */
+	STORE_ATTR_SUBJECT=			0x08, /* X509_NAME * */
+	STORE_ATTR_CERTHASH=			0x09, /* 160 bit string (SHA1) */
+	STORE_ATTR_EMAIL=			0x0a, /* C string */
+	STORE_ATTR_FILENAME=			0x0b, /* C string */
+	STORE_ATTR_TYPE_NUM=			0x0b, /* The amount of known
+							 attribute types */
+	STORE_ATTR_OR=				0xff  /* This is a special
+							 separator, which
+							 expresses the OR
+							 operation.  */
+	} STORE_ATTR_TYPES;
+/* Attribute value sizes.  -1 means unknown, anything else is the required size. */
+extern const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM+1];
+
+typedef enum STORE_certificate_status
+	{
+	STORE_X509_VALID=			0x00,
+	STORE_X509_EXPIRED=			0x01,
+	STORE_X509_SUSPENDED=			0x02,
+	STORE_X509_REVOKED=			0x03
+	} STORE_CERTIFICATE_STATUS;
+
+/* Engine store functions will return a structure that contains all the necessary
+ * information, including revokation status for certificates.  This is really not
+ * needed for application authors, as the ENGINE framework functions will extract
+ * the OpenSSL-specific information when at all possible.  However, for engine
+ * authors, it's crucial to know this structure.  */
+typedef struct STORE_OBJECT_st
+	{
+	STORE_OBJECT_TYPES type;
+	union
+		{
+		struct
+			{
+			STORE_CERTIFICATE_STATUS status;
+			X509 *certificate;
+			} x509;
+		X509_CRL *crl;
+		EVP_PKEY *key;
+		BIGNUM *number;
+		BUF_MEM *arbitrary;
+		} data;
+	} STORE_OBJECT;
+DECLARE_STACK_OF(STORE_OBJECT)
+STORE_OBJECT *STORE_OBJECT_new(void);
+void STORE_OBJECT_free(STORE_OBJECT *data);
+
+
+
+/* The following functions handle the storage. They return 0, a negative number
+   or NULL on error, anything else on success. */
+X509 *STORE_get_certificate(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_certificate(STORE *e, X509 *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_certificate(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_revoke_certificate(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_certificate(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_certificate_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+X509 *STORE_list_certificate_next(STORE *e, void *handle);
+int STORE_list_certificate_end(STORE *e, void *handle);
+int STORE_list_certificate_endp(STORE *e, void *handle);
+EVP_PKEY *STORE_generate_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+EVP_PKEY *STORE_get_private_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_private_key(STORE *e, EVP_PKEY *data,
+	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+int STORE_modify_private_key(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_revoke_private_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_private_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_private_key_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+EVP_PKEY *STORE_list_private_key_next(STORE *e, void *handle);
+int STORE_list_private_key_end(STORE *e, void *handle);
+int STORE_list_private_key_endp(STORE *e, void *handle);
+EVP_PKEY *STORE_get_public_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_public_key(STORE *e, EVP_PKEY *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_public_key(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_revoke_public_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_public_key(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_public_key_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+EVP_PKEY *STORE_list_public_key_next(STORE *e, void *handle);
+int STORE_list_public_key_end(STORE *e, void *handle);
+int STORE_list_public_key_endp(STORE *e, void *handle);
+X509_CRL *STORE_generate_crl(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+X509_CRL *STORE_get_crl(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_crl(STORE *e, X509_CRL *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_crl(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+int STORE_delete_crl(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+void *STORE_list_crl_start(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+X509_CRL *STORE_list_crl_next(STORE *e, void *handle);
+int STORE_list_crl_end(STORE *e, void *handle);
+int STORE_list_crl_endp(STORE *e, void *handle);
+int STORE_store_number(STORE *e, BIGNUM *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_number(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+BIGNUM *STORE_get_number(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_number(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_store_arbitrary(STORE *e, BUF_MEM *data, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_modify_arbitrary(STORE *e, OPENSSL_ITEM search_attributes[],
+	OPENSSL_ITEM add_sttributes[], OPENSSL_ITEM modify_attributes[],
+	OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+BUF_MEM *STORE_get_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+int STORE_delete_arbitrary(STORE *e, OPENSSL_ITEM attributes[],
+	OPENSSL_ITEM parameters[]);
+
+
+/* Create and manipulate methods */
+STORE_METHOD *STORE_create_method(char *name);
+void STORE_destroy_method(STORE_METHOD *store_method);
+
+/* These callback types are use for store handlers */
+typedef int (*STORE_INITIALISE_FUNC_PTR)(STORE *);
+typedef void (*STORE_CLEANUP_FUNC_PTR)(STORE *);
+typedef STORE_OBJECT *(*STORE_GENERATE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef STORE_OBJECT *(*STORE_GET_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef void *(*STORE_START_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef STORE_OBJECT *(*STORE_NEXT_OBJECT_FUNC_PTR)(STORE *, void *handle);
+typedef int (*STORE_END_OBJECT_FUNC_PTR)(STORE *, void *handle);
+typedef int (*STORE_HANDLE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_STORE_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, STORE_OBJECT *data, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_MODIFY_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[], OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_GENERIC_FUNC_PTR)(STORE *, OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
+typedef int (*STORE_CTRL_FUNC_PTR)(STORE *, int cmd, long l, void *p, void (*f)(void));
+
+int STORE_method_set_initialise_function(STORE_METHOD *sm, STORE_INITIALISE_FUNC_PTR init_f);
+int STORE_method_set_cleanup_function(STORE_METHOD *sm, STORE_CLEANUP_FUNC_PTR clean_f);
+int STORE_method_set_generate_function(STORE_METHOD *sm, STORE_GENERATE_OBJECT_FUNC_PTR generate_f);
+int STORE_method_set_get_function(STORE_METHOD *sm, STORE_GET_OBJECT_FUNC_PTR get_f);
+int STORE_method_set_store_function(STORE_METHOD *sm, STORE_STORE_OBJECT_FUNC_PTR store_f);
+int STORE_method_set_modify_function(STORE_METHOD *sm, STORE_MODIFY_OBJECT_FUNC_PTR store_f);
+int STORE_method_set_revoke_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR revoke_f);
+int STORE_method_set_delete_function(STORE_METHOD *sm, STORE_HANDLE_OBJECT_FUNC_PTR delete_f);
+int STORE_method_set_list_start_function(STORE_METHOD *sm, STORE_START_OBJECT_FUNC_PTR list_start_f);
+int STORE_method_set_list_next_function(STORE_METHOD *sm, STORE_NEXT_OBJECT_FUNC_PTR list_next_f);
+int STORE_method_set_list_end_function(STORE_METHOD *sm, STORE_END_OBJECT_FUNC_PTR list_end_f);
+int STORE_method_set_update_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
+int STORE_method_set_lock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
+int STORE_method_set_unlock_store_function(STORE_METHOD *sm, STORE_GENERIC_FUNC_PTR);
+int STORE_method_set_ctrl_function(STORE_METHOD *sm, STORE_CTRL_FUNC_PTR ctrl_f);
+
+STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD *sm);
+STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm);
+STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD *sm);
+STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm);
+STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm);
+STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD *sm);
+STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD *sm);
+STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD *sm);
+STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD *sm);
+STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD *sm);
+STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm);
+STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD *sm);
+STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm);
+STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD *sm);
+STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm);
+
+/* Method helper structures and functions. */
+
+/* This structure is the result of parsing through the information in a list
+   of OPENSSL_ITEMs.  It stores all the necessary information in a structured
+   way.*/
+typedef struct STORE_attr_info_st STORE_ATTR_INFO;
+
+/* Parse a list of OPENSSL_ITEMs and return a pointer to a STORE_ATTR_INFO.
+   Note that we do this in the list form, since the list of OPENSSL_ITEMs can
+   come in blocks separated with STORE_ATTR_OR.  Note that the value returned
+   by STORE_parse_attrs_next() must be freed with STORE_ATTR_INFO_free(). */
+void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes);
+STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle);
+int STORE_parse_attrs_end(void *handle);
+int STORE_parse_attrs_endp(void *handle);
+
+/* Creator and destructor */
+STORE_ATTR_INFO *STORE_ATTR_INFO_new(void);
+int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs);
+
+/* Manipulators */
+char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
+unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs,
+	STORE_ATTR_TYPES code);
+X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
+BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code);
+int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	char *cstr, size_t cstr_size);
+int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	unsigned char *sha1str, size_t sha1str_size);
+int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	X509_NAME *dn);
+int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	BIGNUM *number);
+int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	char *cstr, size_t cstr_size);
+int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	unsigned char *sha1str, size_t sha1str_size);
+int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	X509_NAME *dn);
+int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code,
+	BIGNUM *number);
+
+/* Compare on basis of a bit pattern formed by the STORE_ATTR_TYPES values
+   in each contained attribute. */
+int STORE_ATTR_INFO_compare(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+/* Check if the set of attributes in a is within the range of attributes
+   set in b. */
+int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+/* Check if the set of attributes in a are also set in b. */
+int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+/* Same as STORE_ATTR_INFO_in(), but also checks the attribute values. */
+int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_STORE_strings(void);
+
+/* Error codes for the STORE functions. */
+
+/* Function codes. */
+#define STORE_F_MEM_DELETE				 134
+#define STORE_F_MEM_GENERATE				 135
+#define STORE_F_MEM_LIST_END				 168
+#define STORE_F_MEM_LIST_NEXT				 136
+#define STORE_F_MEM_LIST_START				 137
+#define STORE_F_MEM_MODIFY				 169
+#define STORE_F_MEM_STORE				 138
+#define STORE_F_STORE_ATTR_INFO_GET0_CSTR		 139
+#define STORE_F_STORE_ATTR_INFO_GET0_DN			 140
+#define STORE_F_STORE_ATTR_INFO_GET0_NUMBER		 141
+#define STORE_F_STORE_ATTR_INFO_GET0_SHA1STR		 142
+#define STORE_F_STORE_ATTR_INFO_MODIFY_CSTR		 143
+#define STORE_F_STORE_ATTR_INFO_MODIFY_DN		 144
+#define STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER		 145
+#define STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR		 146
+#define STORE_F_STORE_ATTR_INFO_SET_CSTR		 147
+#define STORE_F_STORE_ATTR_INFO_SET_DN			 148
+#define STORE_F_STORE_ATTR_INFO_SET_NUMBER		 149
+#define STORE_F_STORE_ATTR_INFO_SET_SHA1STR		 150
+#define STORE_F_STORE_CERTIFICATE			 170
+#define STORE_F_STORE_CTRL				 161
+#define STORE_F_STORE_DELETE_ARBITRARY			 158
+#define STORE_F_STORE_DELETE_CERTIFICATE		 102
+#define STORE_F_STORE_DELETE_CRL			 103
+#define STORE_F_STORE_DELETE_NUMBER			 104
+#define STORE_F_STORE_DELETE_PRIVATE_KEY		 105
+#define STORE_F_STORE_DELETE_PUBLIC_KEY			 106
+#define STORE_F_STORE_GENERATE_CRL			 107
+#define STORE_F_STORE_GENERATE_KEY			 108
+#define STORE_F_STORE_GET_ARBITRARY			 159
+#define STORE_F_STORE_GET_CERTIFICATE			 109
+#define STORE_F_STORE_GET_CRL				 110
+#define STORE_F_STORE_GET_NUMBER			 111
+#define STORE_F_STORE_GET_PRIVATE_KEY			 112
+#define STORE_F_STORE_GET_PUBLIC_KEY			 113
+#define STORE_F_STORE_LIST_CERTIFICATE_END		 114
+#define STORE_F_STORE_LIST_CERTIFICATE_ENDP		 153
+#define STORE_F_STORE_LIST_CERTIFICATE_NEXT		 115
+#define STORE_F_STORE_LIST_CERTIFICATE_START		 116
+#define STORE_F_STORE_LIST_CRL_END			 117
+#define STORE_F_STORE_LIST_CRL_ENDP			 154
+#define STORE_F_STORE_LIST_CRL_NEXT			 118
+#define STORE_F_STORE_LIST_CRL_START			 119
+#define STORE_F_STORE_LIST_PRIVATE_KEY_END		 120
+#define STORE_F_STORE_LIST_PRIVATE_KEY_ENDP		 155
+#define STORE_F_STORE_LIST_PRIVATE_KEY_NEXT		 121
+#define STORE_F_STORE_LIST_PRIVATE_KEY_START		 122
+#define STORE_F_STORE_LIST_PUBLIC_KEY_END		 123
+#define STORE_F_STORE_LIST_PUBLIC_KEY_ENDP		 156
+#define STORE_F_STORE_LIST_PUBLIC_KEY_NEXT		 124
+#define STORE_F_STORE_LIST_PUBLIC_KEY_START		 125
+#define STORE_F_STORE_MODIFY_ARBITRARY			 162
+#define STORE_F_STORE_MODIFY_CERTIFICATE		 163
+#define STORE_F_STORE_MODIFY_CRL			 164
+#define STORE_F_STORE_MODIFY_NUMBER			 165
+#define STORE_F_STORE_MODIFY_PRIVATE_KEY		 166
+#define STORE_F_STORE_MODIFY_PUBLIC_KEY			 167
+#define STORE_F_STORE_NEW_ENGINE			 133
+#define STORE_F_STORE_NEW_METHOD			 132
+#define STORE_F_STORE_PARSE_ATTRS_END			 151
+#define STORE_F_STORE_PARSE_ATTRS_ENDP			 172
+#define STORE_F_STORE_PARSE_ATTRS_NEXT			 152
+#define STORE_F_STORE_PARSE_ATTRS_START			 171
+#define STORE_F_STORE_REVOKE_CERTIFICATE		 129
+#define STORE_F_STORE_REVOKE_PRIVATE_KEY		 130
+#define STORE_F_STORE_REVOKE_PUBLIC_KEY			 131
+#define STORE_F_STORE_STORE_ARBITRARY			 157
+#define STORE_F_STORE_STORE_CERTIFICATE			 100
+#define STORE_F_STORE_STORE_CRL				 101
+#define STORE_F_STORE_STORE_NUMBER			 126
+#define STORE_F_STORE_STORE_PRIVATE_KEY			 127
+#define STORE_F_STORE_STORE_PUBLIC_KEY			 128
+
+/* Reason codes. */
+#define STORE_R_ALREADY_HAS_A_VALUE			 127
+#define STORE_R_FAILED_DELETING_ARBITRARY		 132
+#define STORE_R_FAILED_DELETING_CERTIFICATE		 100
+#define STORE_R_FAILED_DELETING_KEY			 101
+#define STORE_R_FAILED_DELETING_NUMBER			 102
+#define STORE_R_FAILED_GENERATING_CRL			 103
+#define STORE_R_FAILED_GENERATING_KEY			 104
+#define STORE_R_FAILED_GETTING_ARBITRARY		 133
+#define STORE_R_FAILED_GETTING_CERTIFICATE		 105
+#define STORE_R_FAILED_GETTING_KEY			 106
+#define STORE_R_FAILED_GETTING_NUMBER			 107
+#define STORE_R_FAILED_LISTING_CERTIFICATES		 108
+#define STORE_R_FAILED_LISTING_KEYS			 109
+#define STORE_R_FAILED_MODIFYING_ARBITRARY		 138
+#define STORE_R_FAILED_MODIFYING_CERTIFICATE		 139
+#define STORE_R_FAILED_MODIFYING_CRL			 140
+#define STORE_R_FAILED_MODIFYING_NUMBER			 141
+#define STORE_R_FAILED_MODIFYING_PRIVATE_KEY		 142
+#define STORE_R_FAILED_MODIFYING_PUBLIC_KEY		 143
+#define STORE_R_FAILED_REVOKING_CERTIFICATE		 110
+#define STORE_R_FAILED_REVOKING_KEY			 111
+#define STORE_R_FAILED_STORING_ARBITRARY		 134
+#define STORE_R_FAILED_STORING_CERTIFICATE		 112
+#define STORE_R_FAILED_STORING_KEY			 113
+#define STORE_R_FAILED_STORING_NUMBER			 114
+#define STORE_R_NOT_IMPLEMENTED				 128
+#define STORE_R_NO_CONTROL_FUNCTION			 144
+#define STORE_R_NO_DELETE_ARBITRARY_FUNCTION		 135
+#define STORE_R_NO_DELETE_NUMBER_FUNCTION		 115
+#define STORE_R_NO_DELETE_OBJECT_FUNCTION		 116
+#define STORE_R_NO_GENERATE_CRL_FUNCTION		 117
+#define STORE_R_NO_GENERATE_OBJECT_FUNCTION		 118
+#define STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION	 136
+#define STORE_R_NO_GET_OBJECT_FUNCTION			 119
+#define STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION		 120
+#define STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION		 131
+#define STORE_R_NO_LIST_OBJECT_END_FUNCTION		 121
+#define STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION		 122
+#define STORE_R_NO_LIST_OBJECT_START_FUNCTION		 123
+#define STORE_R_NO_MODIFY_OBJECT_FUNCTION		 145
+#define STORE_R_NO_REVOKE_OBJECT_FUNCTION		 124
+#define STORE_R_NO_STORE				 129
+#define STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION	 137
+#define STORE_R_NO_STORE_OBJECT_FUNCTION		 125
+#define STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION		 126
+#define STORE_R_NO_VALUE				 130
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/symhacks.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/symhacks.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/symhacks.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,383 @@
+/* ====================================================================
+ * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_SYMHACKS_H
+#define HEADER_SYMHACKS_H
+
+#include <openssl/e_os2.h>
+
+/* Hacks to solve the problem with linkers incapable of handling very long
+   symbol names.  In the case of VMS, the limit is 31 characters on VMS for
+   VAX. */
+#ifdef OPENSSL_SYS_VMS
+
+/* Hack a long name in crypto/ex_data.c */
+#undef CRYPTO_get_ex_data_implementation
+#define CRYPTO_get_ex_data_implementation	CRYPTO_get_ex_data_impl
+#undef CRYPTO_set_ex_data_implementation
+#define CRYPTO_set_ex_data_implementation	CRYPTO_set_ex_data_impl
+
+/* Hack a long name in crypto/asn1/a_mbstr.c */
+#undef ASN1_STRING_set_default_mask_asc
+#define ASN1_STRING_set_default_mask_asc	ASN1_STRING_set_def_mask_asc
+
+#if 0 /* No longer needed, since safestack macro magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */
+#undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO	i2d_ASN1_SET_OF_PKCS7_SIGINF
+#undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO
+#define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO	d2i_ASN1_SET_OF_PKCS7_SIGINF
+#endif
+
+#if 0 /* No longer needed, since safestack macro magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */
+#undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO
+#define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO	i2d_ASN1_SET_OF_PKCS7_RECINF
+#undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO
+#define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO	d2i_ASN1_SET_OF_PKCS7_RECINF
+#endif
+
+#if 0 /* No longer needed, since safestack macro magic does the job */
+/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */
+#undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION
+#define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION	i2d_ASN1_SET_OF_ACC_DESC
+#undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION
+#define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION	d2i_ASN1_SET_OF_ACC_DESC
+#endif
+
+/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */
+#undef PEM_read_NETSCAPE_CERT_SEQUENCE
+#define PEM_read_NETSCAPE_CERT_SEQUENCE		PEM_read_NS_CERT_SEQ
+#undef PEM_write_NETSCAPE_CERT_SEQUENCE
+#define PEM_write_NETSCAPE_CERT_SEQUENCE	PEM_write_NS_CERT_SEQ
+#undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE
+#define PEM_read_bio_NETSCAPE_CERT_SEQUENCE	PEM_read_bio_NS_CERT_SEQ
+#undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE
+#define PEM_write_bio_NETSCAPE_CERT_SEQUENCE	PEM_write_bio_NS_CERT_SEQ
+#undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE
+#define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE	PEM_write_cb_bio_NS_CERT_SEQ
+
+/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */
+#undef PEM_read_PKCS8_PRIV_KEY_INFO
+#define PEM_read_PKCS8_PRIV_KEY_INFO		PEM_read_P8_PRIV_KEY_INFO
+#undef PEM_write_PKCS8_PRIV_KEY_INFO
+#define PEM_write_PKCS8_PRIV_KEY_INFO		PEM_write_P8_PRIV_KEY_INFO
+#undef PEM_read_bio_PKCS8_PRIV_KEY_INFO
+#define PEM_read_bio_PKCS8_PRIV_KEY_INFO	PEM_read_bio_P8_PRIV_KEY_INFO
+#undef PEM_write_bio_PKCS8_PRIV_KEY_INFO
+#define PEM_write_bio_PKCS8_PRIV_KEY_INFO	PEM_write_bio_P8_PRIV_KEY_INFO
+#undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO
+#define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO	PEM_wrt_cb_bio_P8_PRIV_KEY_INFO
+
+/* Hack other PEM names */
+#undef PEM_write_bio_PKCS8PrivateKey_nid
+#define PEM_write_bio_PKCS8PrivateKey_nid	PEM_write_bio_PKCS8PrivKey_nid
+
+/* Hack some long X509 names */
+#undef X509_REVOKED_get_ext_by_critical
+#define X509_REVOKED_get_ext_by_critical	X509_REVOKED_get_ext_by_critic
+#undef X509_policy_tree_get0_user_policies
+#define X509_policy_tree_get0_user_policies	X509_pcy_tree_get0_usr_policies
+#undef X509_policy_node_get0_qualifiers
+#define X509_policy_node_get0_qualifiers	X509_pcy_node_get0_qualifiers
+#undef X509_STORE_CTX_get_explicit_policy
+#define X509_STORE_CTX_get_explicit_policy	X509_STORE_CTX_get_expl_policy
+
+/* Hack some long CRYPTO names */
+#undef CRYPTO_set_dynlock_destroy_callback
+#define CRYPTO_set_dynlock_destroy_callback     CRYPTO_set_dynlock_destroy_cb
+#undef CRYPTO_set_dynlock_create_callback
+#define CRYPTO_set_dynlock_create_callback      CRYPTO_set_dynlock_create_cb
+#undef CRYPTO_set_dynlock_lock_callback
+#define CRYPTO_set_dynlock_lock_callback        CRYPTO_set_dynlock_lock_cb
+#undef CRYPTO_get_dynlock_lock_callback
+#define CRYPTO_get_dynlock_lock_callback        CRYPTO_get_dynlock_lock_cb
+#undef CRYPTO_get_dynlock_destroy_callback
+#define CRYPTO_get_dynlock_destroy_callback     CRYPTO_get_dynlock_destroy_cb
+#undef CRYPTO_get_dynlock_create_callback
+#define CRYPTO_get_dynlock_create_callback      CRYPTO_get_dynlock_create_cb
+#undef CRYPTO_set_locked_mem_ex_functions
+#define CRYPTO_set_locked_mem_ex_functions      CRYPTO_set_locked_mem_ex_funcs
+#undef CRYPTO_get_locked_mem_ex_functions
+#define CRYPTO_get_locked_mem_ex_functions      CRYPTO_get_locked_mem_ex_funcs
+
+/* Hack some long SSL names */
+#undef SSL_CTX_set_default_verify_paths
+#define SSL_CTX_set_default_verify_paths        SSL_CTX_set_def_verify_paths
+#undef SSL_get_ex_data_X509_STORE_CTX_idx
+#define SSL_get_ex_data_X509_STORE_CTX_idx      SSL_get_ex_d_X509_STORE_CTX_idx
+#undef SSL_add_file_cert_subjects_to_stack
+#define SSL_add_file_cert_subjects_to_stack     SSL_add_file_cert_subjs_to_stk
+#undef SSL_add_dir_cert_subjects_to_stack
+#define SSL_add_dir_cert_subjects_to_stack      SSL_add_dir_cert_subjs_to_stk
+#undef SSL_CTX_use_certificate_chain_file
+#define SSL_CTX_use_certificate_chain_file      SSL_CTX_use_cert_chain_file
+#undef SSL_CTX_set_cert_verify_callback
+#define SSL_CTX_set_cert_verify_callback        SSL_CTX_set_cert_verify_cb
+#undef SSL_CTX_set_default_passwd_cb_userdata
+#define SSL_CTX_set_default_passwd_cb_userdata  SSL_CTX_set_def_passwd_cb_ud
+#undef SSL_COMP_get_compression_methods
+#define SSL_COMP_get_compression_methods	SSL_COMP_get_compress_methods
+
+/* Hack some long ENGINE names */
+#undef ENGINE_get_default_BN_mod_exp_crt
+#define ENGINE_get_default_BN_mod_exp_crt	ENGINE_get_def_BN_mod_exp_crt
+#undef ENGINE_set_default_BN_mod_exp_crt
+#define ENGINE_set_default_BN_mod_exp_crt	ENGINE_set_def_BN_mod_exp_crt
+#undef ENGINE_set_load_privkey_function
+#define ENGINE_set_load_privkey_function        ENGINE_set_load_privkey_fn
+#undef ENGINE_get_load_privkey_function
+#define ENGINE_get_load_privkey_function        ENGINE_get_load_privkey_fn
+
+/* Hack some long OCSP names */
+#undef OCSP_REQUEST_get_ext_by_critical
+#define OCSP_REQUEST_get_ext_by_critical        OCSP_REQUEST_get_ext_by_crit
+#undef OCSP_BASICRESP_get_ext_by_critical
+#define OCSP_BASICRESP_get_ext_by_critical      OCSP_BASICRESP_get_ext_by_crit
+#undef OCSP_SINGLERESP_get_ext_by_critical
+#define OCSP_SINGLERESP_get_ext_by_critical     OCSP_SINGLERESP_get_ext_by_crit
+
+/* Hack some long DES names */
+#undef _ossl_old_des_ede3_cfb64_encrypt
+#define _ossl_old_des_ede3_cfb64_encrypt	_ossl_odes_ede3_cfb64_encrypt
+#undef _ossl_old_des_ede3_ofb64_encrypt
+#define _ossl_old_des_ede3_ofb64_encrypt	_ossl_odes_ede3_ofb64_encrypt
+
+/* Hack some long EVP names */
+#undef OPENSSL_add_all_algorithms_noconf
+#define OPENSSL_add_all_algorithms_noconf	OPENSSL_add_all_algo_noconf
+#undef OPENSSL_add_all_algorithms_conf
+#define OPENSSL_add_all_algorithms_conf		OPENSSL_add_all_algo_conf
+
+/* Hack some long EC names */
+#undef EC_GROUP_set_point_conversion_form
+#define EC_GROUP_set_point_conversion_form	EC_GROUP_set_point_conv_form
+#undef EC_GROUP_get_point_conversion_form
+#define EC_GROUP_get_point_conversion_form	EC_GROUP_get_point_conv_form
+#undef EC_GROUP_clear_free_all_extra_data
+#define EC_GROUP_clear_free_all_extra_data	EC_GROUP_clr_free_all_xtra_data
+#undef EC_POINT_set_Jprojective_coordinates_GFp
+#define EC_POINT_set_Jprojective_coordinates_GFp \
+                                                EC_POINT_set_Jproj_coords_GFp
+#undef EC_POINT_get_Jprojective_coordinates_GFp
+#define EC_POINT_get_Jprojective_coordinates_GFp \
+                                                EC_POINT_get_Jproj_coords_GFp
+#undef EC_POINT_set_affine_coordinates_GFp
+#define EC_POINT_set_affine_coordinates_GFp     EC_POINT_set_affine_coords_GFp
+#undef EC_POINT_get_affine_coordinates_GFp
+#define EC_POINT_get_affine_coordinates_GFp     EC_POINT_get_affine_coords_GFp
+#undef EC_POINT_set_compressed_coordinates_GFp
+#define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp
+#undef EC_POINT_set_affine_coordinates_GF2m
+#define EC_POINT_set_affine_coordinates_GF2m    EC_POINT_set_affine_coords_GF2m
+#undef EC_POINT_get_affine_coordinates_GF2m
+#define EC_POINT_get_affine_coordinates_GF2m    EC_POINT_get_affine_coords_GF2m
+#undef EC_POINT_set_compressed_coordinates_GF2m
+#define EC_POINT_set_compressed_coordinates_GF2m \
+                                                EC_POINT_set_compr_coords_GF2m
+#undef ec_GF2m_simple_group_clear_finish
+#define ec_GF2m_simple_group_clear_finish        ec_GF2m_simple_grp_clr_finish
+#undef ec_GF2m_simple_group_check_discriminant
+#define ec_GF2m_simple_group_check_discriminant	ec_GF2m_simple_grp_chk_discrim
+#undef ec_GF2m_simple_point_clear_finish
+#define ec_GF2m_simple_point_clear_finish        ec_GF2m_simple_pt_clr_finish
+#undef ec_GF2m_simple_point_set_to_infinity
+#define ec_GF2m_simple_point_set_to_infinity     ec_GF2m_simple_pt_set_to_inf
+#undef ec_GF2m_simple_points_make_affine
+#define ec_GF2m_simple_points_make_affine        ec_GF2m_simple_pts_make_affine
+#undef ec_GF2m_simple_point_set_affine_coordinates
+#define ec_GF2m_simple_point_set_affine_coordinates \
+                                                ec_GF2m_smp_pt_set_af_coords
+#undef ec_GF2m_simple_point_get_affine_coordinates
+#define ec_GF2m_simple_point_get_affine_coordinates \
+                                                ec_GF2m_smp_pt_get_af_coords
+#undef ec_GF2m_simple_set_compressed_coordinates
+#define ec_GF2m_simple_set_compressed_coordinates \
+                                                ec_GF2m_smp_set_compr_coords
+#undef ec_GFp_simple_group_set_curve_GFp
+#define ec_GFp_simple_group_set_curve_GFp       ec_GFp_simple_grp_set_curve_GFp
+#undef ec_GFp_simple_group_get_curve_GFp
+#define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
+#undef ec_GFp_simple_group_clear_finish
+#define ec_GFp_simple_group_clear_finish        ec_GFp_simple_grp_clear_finish
+#undef ec_GFp_simple_group_set_generator
+#define ec_GFp_simple_group_set_generator       ec_GFp_simple_grp_set_generator
+#undef ec_GFp_simple_group_get0_generator
+#define ec_GFp_simple_group_get0_generator      ec_GFp_simple_grp_gt0_generator
+#undef ec_GFp_simple_group_get_cofactor
+#define ec_GFp_simple_group_get_cofactor        ec_GFp_simple_grp_get_cofactor
+#undef ec_GFp_simple_point_clear_finish
+#define ec_GFp_simple_point_clear_finish        ec_GFp_simple_pt_clear_finish
+#undef ec_GFp_simple_point_set_to_infinity
+#define ec_GFp_simple_point_set_to_infinity     ec_GFp_simple_pt_set_to_inf
+#undef ec_GFp_simple_points_make_affine
+#define ec_GFp_simple_points_make_affine        ec_GFp_simple_pts_make_affine
+#undef ec_GFp_simple_group_get_curve_GFp
+#define ec_GFp_simple_group_get_curve_GFp       ec_GFp_simple_grp_get_curve_GFp
+#undef ec_GFp_simple_set_Jprojective_coordinates_GFp
+#define ec_GFp_simple_set_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_set_Jproj_coords_GFp
+#undef ec_GFp_simple_get_Jprojective_coordinates_GFp
+#define ec_GFp_simple_get_Jprojective_coordinates_GFp \
+                                                ec_GFp_smp_get_Jproj_coords_GFp
+#undef ec_GFp_simple_point_set_affine_coordinates_GFp
+#define ec_GFp_simple_point_set_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_set_af_coords_GFp
+#undef ec_GFp_simple_point_get_affine_coordinates_GFp
+#define ec_GFp_simple_point_get_affine_coordinates_GFp \
+                                                ec_GFp_smp_pt_get_af_coords_GFp
+#undef ec_GFp_simple_set_compressed_coordinates_GFp
+#define ec_GFp_simple_set_compressed_coordinates_GFp \
+                                                ec_GFp_smp_set_compr_coords_GFp
+#undef ec_GFp_simple_point_set_affine_coordinates
+#define ec_GFp_simple_point_set_affine_coordinates \
+                                                ec_GFp_smp_pt_set_af_coords
+#undef ec_GFp_simple_point_get_affine_coordinates
+#define ec_GFp_simple_point_get_affine_coordinates \
+                                                ec_GFp_smp_pt_get_af_coords
+#undef ec_GFp_simple_set_compressed_coordinates
+#define ec_GFp_simple_set_compressed_coordinates \
+                                                ec_GFp_smp_set_compr_coords
+#undef ec_GFp_simple_group_check_discriminant
+#define ec_GFp_simple_group_check_discriminant	ec_GFp_simple_grp_chk_discrim
+
+/* Hack som long STORE names */
+#undef STORE_method_set_initialise_function
+#define STORE_method_set_initialise_function	STORE_meth_set_initialise_fn
+#undef STORE_method_set_cleanup_function
+#define STORE_method_set_cleanup_function	STORE_meth_set_cleanup_fn
+#undef STORE_method_set_generate_function
+#define STORE_method_set_generate_function	STORE_meth_set_generate_fn
+#undef STORE_method_set_modify_function
+#define STORE_method_set_modify_function	STORE_meth_set_modify_fn
+#undef STORE_method_set_revoke_function
+#define STORE_method_set_revoke_function	STORE_meth_set_revoke_fn
+#undef STORE_method_set_delete_function
+#define STORE_method_set_delete_function	STORE_meth_set_delete_fn
+#undef STORE_method_set_list_start_function
+#define STORE_method_set_list_start_function	STORE_meth_set_list_start_fn
+#undef STORE_method_set_list_next_function
+#define STORE_method_set_list_next_function	STORE_meth_set_list_next_fn
+#undef STORE_method_set_list_end_function
+#define STORE_method_set_list_end_function	STORE_meth_set_list_end_fn
+#undef STORE_method_set_update_store_function
+#define STORE_method_set_update_store_function	STORE_meth_set_update_store_fn
+#undef STORE_method_set_lock_store_function
+#define STORE_method_set_lock_store_function	STORE_meth_set_lock_store_fn
+#undef STORE_method_set_unlock_store_function
+#define STORE_method_set_unlock_store_function	STORE_meth_set_unlock_store_fn
+#undef STORE_method_get_initialise_function
+#define STORE_method_get_initialise_function	STORE_meth_get_initialise_fn
+#undef STORE_method_get_cleanup_function
+#define STORE_method_get_cleanup_function	STORE_meth_get_cleanup_fn
+#undef STORE_method_get_generate_function
+#define STORE_method_get_generate_function	STORE_meth_get_generate_fn
+#undef STORE_method_get_modify_function
+#define STORE_method_get_modify_function	STORE_meth_get_modify_fn
+#undef STORE_method_get_revoke_function
+#define STORE_method_get_revoke_function	STORE_meth_get_revoke_fn
+#undef STORE_method_get_delete_function
+#define STORE_method_get_delete_function	STORE_meth_get_delete_fn
+#undef STORE_method_get_list_start_function
+#define STORE_method_get_list_start_function	STORE_meth_get_list_start_fn
+#undef STORE_method_get_list_next_function
+#define STORE_method_get_list_next_function	STORE_meth_get_list_next_fn
+#undef STORE_method_get_list_end_function
+#define STORE_method_get_list_end_function	STORE_meth_get_list_end_fn
+#undef STORE_method_get_update_store_function
+#define STORE_method_get_update_store_function	STORE_meth_get_update_store_fn
+#undef STORE_method_get_lock_store_function
+#define STORE_method_get_lock_store_function	STORE_meth_get_lock_store_fn
+#undef STORE_method_get_unlock_store_function
+#define STORE_method_get_unlock_store_function	STORE_meth_get_unlock_store_fn
+
+#endif /* defined OPENSSL_SYS_VMS */
+
+
+/* Case insensiteve linking causes problems.... */
+#if defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2)
+#undef ERR_load_CRYPTO_strings
+#define ERR_load_CRYPTO_strings			ERR_load_CRYPTOlib_strings
+#undef OCSP_crlID_new
+#define OCSP_crlID_new                          OCSP_crlID2_new
+
+#undef d2i_ECPARAMETERS
+#define d2i_ECPARAMETERS                        d2i_UC_ECPARAMETERS
+#undef i2d_ECPARAMETERS
+#define i2d_ECPARAMETERS                        i2d_UC_ECPARAMETERS
+#undef d2i_ECPKPARAMETERS
+#define d2i_ECPKPARAMETERS                      d2i_UC_ECPKPARAMETERS
+#undef i2d_ECPKPARAMETERS
+#define i2d_ECPKPARAMETERS                      i2d_UC_ECPKPARAMETERS
+
+/* These functions do not seem to exist!  However, I'm paranoid...
+   Original command in x509v3.h:
+   These functions are being redefined in another directory,
+   and clash when the linker is case-insensitive, so let's
+   hide them a little, by giving them an extra 'o' at the
+   beginning of the name... */
+#undef X509v3_cleanup_extensions
+#define X509v3_cleanup_extensions               oX509v3_cleanup_extensions
+#undef X509v3_add_extension
+#define X509v3_add_extension                    oX509v3_add_extension
+#undef X509v3_add_netscape_extensions
+#define X509v3_add_netscape_extensions          oX509v3_add_netscape_extensions
+#undef X509v3_add_standard_extensions
+#define X509v3_add_standard_extensions          oX509v3_add_standard_extensions
+
+
+#endif
+
+
+#endif /* ! defined HEADER_VMS_IDHACKS_H */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/tls1.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/tls1.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/tls1.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,291 @@
+/* ssl/tls1.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ *
+ * Portions of the attached software ("Contribution") are developed by 
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
+ *
+ * The Contribution is licensed pursuant to the OpenSSL open source
+ * license provided above.
+ *
+ * ECC cipher suite support in OpenSSL originally written by
+ * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
+ *
+ */
+
+#ifndef HEADER_TLS1_H 
+#define HEADER_TLS1_H 
+
+#include <openssl/buffer.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES	1
+
+#define TLS1_VERSION			0x0301
+#define TLS1_VERSION_MAJOR		0x03
+#define TLS1_VERSION_MINOR		0x01
+
+#define TLS1_AD_DECRYPTION_FAILED	21
+#define TLS1_AD_RECORD_OVERFLOW		22
+#define TLS1_AD_UNKNOWN_CA		48	/* fatal */
+#define TLS1_AD_ACCESS_DENIED		49	/* fatal */
+#define TLS1_AD_DECODE_ERROR		50	/* fatal */
+#define TLS1_AD_DECRYPT_ERROR		51
+#define TLS1_AD_EXPORT_RESTRICTION	60	/* fatal */
+#define TLS1_AD_PROTOCOL_VERSION	70	/* fatal */
+#define TLS1_AD_INSUFFICIENT_SECURITY	71	/* fatal */
+#define TLS1_AD_INTERNAL_ERROR		80	/* fatal */
+#define TLS1_AD_USER_CANCELLED		90
+#define TLS1_AD_NO_RENEGOTIATION	100
+
+/* Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt
+ * (available if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see
+ * s3_lib.c).  We actually treat them like SSL 3.0 ciphers, which we probably
+ * shouldn't. */
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5		0x03000060
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	0x03000061
+#define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA		0x03000062
+#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	0x03000063
+#define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA		0x03000064
+#define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA	0x03000065
+#define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA		0x03000066
+
+/* AES ciphersuites from RFC3268 */
+
+#define TLS1_CK_RSA_WITH_AES_128_SHA			0x0300002F
+#define TLS1_CK_DH_DSS_WITH_AES_128_SHA			0x03000030
+#define TLS1_CK_DH_RSA_WITH_AES_128_SHA			0x03000031
+#define TLS1_CK_DHE_DSS_WITH_AES_128_SHA		0x03000032
+#define TLS1_CK_DHE_RSA_WITH_AES_128_SHA		0x03000033
+#define TLS1_CK_ADH_WITH_AES_128_SHA			0x03000034
+
+#define TLS1_CK_RSA_WITH_AES_256_SHA			0x03000035
+#define TLS1_CK_DH_DSS_WITH_AES_256_SHA			0x03000036
+#define TLS1_CK_DH_RSA_WITH_AES_256_SHA			0x03000037
+#define TLS1_CK_DHE_DSS_WITH_AES_256_SHA		0x03000038
+#define TLS1_CK_DHE_RSA_WITH_AES_256_SHA		0x03000039
+#define TLS1_CK_ADH_WITH_AES_256_SHA			0x0300003A
+
+/* ECC ciphersuites from draft-ietf-tls-ecc-01.txt (Mar 15, 2001).
+ * XXX NOTE: There is a bug in the draft, cipher numbers 4B, and 4C
+ * are defined twice so we define ECDH_ECDSA_EXPORT cipher
+ * suites to use 5B and 5C instead (this may change with future
+ * updates to the IETF draft).
+ */
+/* draft-ietf-tls-ecc-03.txt (June 2003) gives a changed list of
+ * ciphersuites, but does not define numbers for all of them
+ * because of possible conflicts with other Internet Drafts;
+ * most numbers are still subject to change. */
+#define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA                0x03000047
+#define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA             0x03000048
+#define TLS1_CK_ECDH_ECDSA_WITH_DES_CBC_SHA             0x03000049
+#define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA        0x0300004A
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA         0x0300004B
+#define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA         0x0300004C
+#define TLS1_CK_ECDH_ECDSA_EXPORT_WITH_RC4_40_SHA       0x0300005B
+#define TLS1_CK_ECDH_ECDSA_EXPORT_WITH_RC4_56_SHA       0x0300005C
+
+#define TLS1_CK_ECDH_RSA_WITH_NULL_SHA                  0x0300004D
+#define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA               0x0300004E
+#define TLS1_CK_ECDH_RSA_WITH_DES_CBC_SHA               0x0300004F
+#define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA          0x03000050
+#define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA           0x03000051
+#define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA           0x03000052
+#define TLS1_CK_ECDH_RSA_EXPORT_WITH_RC4_40_SHA         0x03000053
+#define TLS1_CK_ECDH_RSA_EXPORT_WITH_RC4_56_SHA         0x03000054
+
+#define TLS1_CK_ECDH_anon_WITH_NULL_SHA                 0x03000055
+#define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA              0x03000056
+#define TLS1_CK_ECDH_anon_WITH_DES_CBC_SHA              0x03000057
+#define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA         0x03000058
+#define TLS1_CK_ECDH_anon_EXPORT_WITH_DES_40_CBC_SHA    0x03000059
+#define TLS1_CK_ECDH_anon_EXPORT_WITH_RC4_40_SHA        0x0300005A
+
+/* XXX: ECC ciphersuites offering forward secrecy are not yet specified
+ * in the ECC/TLS draft but our code allows them to be implemented
+ * very easily. To add such a cipher suite, one needs to add two constant
+ * definitions to this file and a new structure in s3_lib.c. We illustrate
+ * the process for the made-up ciphers ECDHE-ECDSA-AES128-SHA and
+ * ECDHE-RSA-AES128-SHA.
+ */
+#define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA        0x03000077
+#define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA          0x03000078
+
+
+/* XXX
+ * Inconsistency alert:
+ * The OpenSSL names of ciphers with ephemeral DH here include the string
+ * "DHE", while elsewhere it has always been "EDH".
+ * (The alias for the list of all such ciphers also is "EDH".)
+ * The specifications speak of "EDH"; maybe we should allow both forms
+ * for everything. */
+#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5		"EXP1024-RC4-MD5"
+#define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5	"EXP1024-RC2-CBC-MD5"
+#define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA	"EXP1024-DES-CBC-SHA"
+#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA	"EXP1024-DHE-DSS-DES-CBC-SHA"
+#define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA		"EXP1024-RC4-SHA"
+#define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA	"EXP1024-DHE-DSS-RC4-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA		"DHE-DSS-RC4-SHA"
+
+/* AES ciphersuites from RFC3268 */
+#define TLS1_TXT_RSA_WITH_AES_128_SHA			"AES128-SHA"
+#define TLS1_TXT_DH_DSS_WITH_AES_128_SHA		"DH-DSS-AES128-SHA"
+#define TLS1_TXT_DH_RSA_WITH_AES_128_SHA		"DH-RSA-AES128-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA		"DHE-DSS-AES128-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA		"DHE-RSA-AES128-SHA"
+#define TLS1_TXT_ADH_WITH_AES_128_SHA			"ADH-AES128-SHA"
+
+#define TLS1_TXT_RSA_WITH_AES_256_SHA			"AES256-SHA"
+#define TLS1_TXT_DH_DSS_WITH_AES_256_SHA		"DH-DSS-AES256-SHA"
+#define TLS1_TXT_DH_RSA_WITH_AES_256_SHA		"DH-RSA-AES256-SHA"
+#define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA		"DHE-DSS-AES256-SHA"
+#define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA		"DHE-RSA-AES256-SHA"
+#define TLS1_TXT_ADH_WITH_AES_256_SHA			"ADH-AES256-SHA"
+
+/* ECC ciphersuites from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */
+#define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA               "ECDH-ECDSA-NULL-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA            "ECDH-ECDSA-RC4-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_DES_CBC_SHA            "ECDH-ECDSA-DES-CBC-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA       "ECDH-ECDSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA        "ECDH-ECDSA-AES128-SHA"
+#define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA        "ECDH-ECDSA-AES256-SHA"
+#define TLS1_TXT_ECDH_ECDSA_EXPORT_WITH_RC4_40_SHA      "EXP-ECDH-ECDSA-RC4-40-SHA"
+#define TLS1_TXT_ECDH_ECDSA_EXPORT_WITH_RC4_56_SHA      "EXP-ECDH-ECDSA-RC4-56-SHA"
+
+#define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA                 "ECDH-RSA-NULL-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA              "ECDH-RSA-RC4-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_DES_CBC_SHA              "ECDH-RSA-DES-CBC-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA         "ECDH-RSA-DES-CBC3-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA          "ECDH-RSA-AES128-SHA"
+#define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA          "ECDH-RSA-AES256-SHA"
+#define TLS1_TXT_ECDH_RSA_EXPORT_WITH_RC4_40_SHA        "EXP-ECDH-RSA-RC4-40-SHA"
+#define TLS1_TXT_ECDH_RSA_EXPORT_WITH_RC4_56_SHA        "EXP-ECDH-RSA-RC4-56-SHA"
+
+#define TLS1_TXT_ECDH_anon_WITH_NULL_SHA                "AECDH-NULL-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA             "AECDH-RC4-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_DES_CBC_SHA             "AECDH-DES-CBC-SHA"
+#define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA        "AECDH-DES-CBC3-SHA"
+#define TLS1_TXT_ECDH_anon_EXPORT_WITH_DES_40_CBC_SHA   "EXP-AECDH-DES-40-CBC-SHA"
+#define TLS1_TXT_ECDH_anon_EXPORT_WITH_RC4_40_SHA       "EXP-AECDH-RC4-40-SHA"
+
+/* XXX: Made-up ECC cipher suites offering forward secrecy. This is for 
+ * illustration only. 
+ */
+#define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA       "ECDHE-ECDSA-AES128-SHA"
+#define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA         "ECDHE-RSA-AES128-SHA"
+
+
+#define TLS_CT_RSA_SIGN			1
+#define TLS_CT_DSS_SIGN			2
+#define TLS_CT_RSA_FIXED_DH		3
+#define TLS_CT_DSS_FIXED_DH		4
+#define TLS_CT_ECDSA_SIGN		5
+#define TLS_CT_RSA_FIXED_ECDH		6
+#define TLS_CT_ECDSA_FIXED_ECDH 	7
+#define TLS_CT_NUMBER			7
+
+#define TLS1_FINISH_MAC_LENGTH		12
+
+#define TLS_MD_MAX_CONST_SIZE			20
+#define TLS_MD_CLIENT_FINISH_CONST		"client finished"
+#define TLS_MD_CLIENT_FINISH_CONST_SIZE		15
+#define TLS_MD_SERVER_FINISH_CONST		"server finished"
+#define TLS_MD_SERVER_FINISH_CONST_SIZE		15
+#define TLS_MD_SERVER_WRITE_KEY_CONST		"server write key"
+#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE	16
+#define TLS_MD_KEY_EXPANSION_CONST		"key expansion"
+#define TLS_MD_KEY_EXPANSION_CONST_SIZE		13
+#define TLS_MD_CLIENT_WRITE_KEY_CONST		"client write key"
+#define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE	16
+#define TLS_MD_SERVER_WRITE_KEY_CONST		"server write key"
+#define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE	16
+#define TLS_MD_IV_BLOCK_CONST			"IV block"
+#define TLS_MD_IV_BLOCK_CONST_SIZE		8
+#define TLS_MD_MASTER_SECRET_CONST		"master secret"
+#define TLS_MD_MASTER_SECRET_CONST_SIZE		13
+
+#ifdef CHARSET_EBCDIC
+#undef TLS_MD_CLIENT_FINISH_CONST
+#define TLS_MD_CLIENT_FINISH_CONST    "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64"  /*client finished*/
+#undef TLS_MD_SERVER_FINISH_CONST
+#define TLS_MD_SERVER_FINISH_CONST    "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64"  /*server finished*/
+#undef TLS_MD_SERVER_WRITE_KEY_CONST
+#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*server write key*/
+#undef TLS_MD_KEY_EXPANSION_CONST
+#define TLS_MD_KEY_EXPANSION_CONST    "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e"  /*key expansion*/
+#undef TLS_MD_CLIENT_WRITE_KEY_CONST
+#define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*client write key*/
+#undef TLS_MD_SERVER_WRITE_KEY_CONST
+#define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79"  /*server write key*/
+#undef TLS_MD_IV_BLOCK_CONST
+#define TLS_MD_IV_BLOCK_CONST         "\x49\x56\x20\x62\x6c\x6f\x63\x6b"  /*IV block*/
+#undef TLS_MD_MASTER_SECRET_CONST
+#define TLS_MD_MASTER_SECRET_CONST    "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"  /*master secret*/
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/tmdiff.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/tmdiff.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/tmdiff.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,94 @@
+/* crypto/tmdiff.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+/* Header for dynamic hash table routines
+ * Author - Eric Young
+ */
+/* ... erm yeah, "dynamic hash tables" you say?
+ * 
+ * And what would dynamic hash tables have to do with any of this code *now*?
+ * AFAICS, this code is only referenced by crypto/bn/exp.c which is an unused
+ * file that I doubt compiles any more. speed.c is the only thing that could
+ * use this (and it has nothing to do with hash tables), yet it instead has its
+ * own duplication of all this stuff and looks, if anything, more complete. See
+ * the corresponding note in apps/speed.c.
+ * The Bemused - Geoff
+ */
+
+#ifndef HEADER_TMDIFF_H
+#define HEADER_TMDIFF_H
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct ms_tm MS_TM;
+
+MS_TM *ms_time_new(void );
+void ms_time_free(MS_TM *a);
+void ms_time_get(MS_TM *a);
+double ms_time_diff(MS_TM *start, MS_TM *end);
+int ms_time_cmp(const MS_TM *ap, const MS_TM *bp);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
+
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/txt_db.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/txt_db.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/txt_db.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,109 @@
+/* crypto/txt_db/txt_db.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_TXT_DB_H
+#define HEADER_TXT_DB_H
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/stack.h>
+#include <openssl/lhash.h>
+
+#define DB_ERROR_OK			0
+#define DB_ERROR_MALLOC			1
+#define DB_ERROR_INDEX_CLASH    	2
+#define DB_ERROR_INDEX_OUT_OF_RANGE	3
+#define DB_ERROR_NO_INDEX		4
+#define DB_ERROR_INSERT_INDEX_CLASH    	5
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef struct txt_db_st
+	{
+	int num_fields;
+	STACK /* char ** */ *data;
+	LHASH **index;
+	int (**qual)(char **);
+	long error;
+	long arg1;
+	long arg2;
+	char **arg_row;
+	} TXT_DB;
+
+#ifndef OPENSSL_NO_BIO
+TXT_DB *TXT_DB_read(BIO *in, int num);
+long TXT_DB_write(BIO *out, TXT_DB *db);
+#else
+TXT_DB *TXT_DB_read(char *in, int num);
+long TXT_DB_write(char *out, TXT_DB *db);
+#endif
+int TXT_DB_create_index(TXT_DB *db,int field,int (*qual)(char **),
+		LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp);
+void TXT_DB_free(TXT_DB *db);
+char **TXT_DB_get_by_index(TXT_DB *db, int idx, char **value);
+int TXT_DB_insert(TXT_DB *db,char **value);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ui.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ui.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ui.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,381 @@
+/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_H
+#define HEADER_UI_H
+
+#ifndef OPENSSL_NO_DEPRECATED
+#include <openssl/crypto.h>
+#endif
+#include <openssl/safestack.h>
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Declared already in ossl_typ.h */
+/* typedef struct ui_st UI; */
+/* typedef struct ui_method_st UI_METHOD; */
+
+
+/* All the following functions return -1 or NULL on error and in some cases
+   (UI_process()) -2 if interrupted or in some other way cancelled.
+   When everything is fine, they return 0, a positive value or a non-NULL
+   pointer, all depending on their purpose. */
+
+/* Creators and destructor.   */
+UI *UI_new(void);
+UI *UI_new_method(const UI_METHOD *method);
+void UI_free(UI *ui);
+
+/* The following functions are used to add strings to be printed and prompt
+   strings to prompt for data.  The names are UI_{add,dup}_<function>_string
+   and UI_{add,dup}_input_boolean.
+
+   UI_{add,dup}_<function>_string have the following meanings:
+	add	add a text or prompt string.  The pointers given to these
+		functions are used verbatim, no copying is done.
+	dup	make a copy of the text or prompt string, then add the copy
+		to the collection of strings in the user interface.
+	<function>
+		The function is a name for the functionality that the given
+		string shall be used for.  It can be one of:
+			input	use the string as data prompt.
+			verify	use the string as verification prompt.  This
+				is used to verify a previous input.
+			info	use the string for informational output.
+			error	use the string for error output.
+   Honestly, there's currently no difference between info and error for the
+   moment.
+
+   UI_{add,dup}_input_boolean have the same semantics for "add" and "dup",
+   and are typically used when one wants to prompt for a yes/no response.
+
+
+   All of the functions in this group take a UI and a prompt string.
+   The string input and verify addition functions also take a flag argument,
+   a buffer for the result to end up with, a minimum input size and a maximum
+   input size (the result buffer MUST be large enough to be able to contain
+   the maximum number of characters).  Additionally, the verify addition
+   functions takes another buffer to compare the result against.
+   The boolean input functions take an action description string (which should
+   be safe to ignore if the expected user action is obvious, for example with
+   a dialog box with an OK button and a Cancel button), a string of acceptable
+   characters to mean OK and to mean Cancel.  The two last strings are checked
+   to make sure they don't have common characters.  Additionally, the same
+   flag argument as for the string input is taken, as well as a result buffer.
+   The result buffer is required to be at least one byte long.  Depending on
+   the answer, the first character from the OK or the Cancel character strings
+   will be stored in the first byte of the result buffer.  No NUL will be
+   added, so the result is *not* a string.
+
+   On success, the all return an index of the added information.  That index
+   is usefull when retrieving results with UI_get0_result(). */
+int UI_add_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize);
+int UI_dup_input_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize);
+int UI_add_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf);
+int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
+	char *result_buf, int minsize, int maxsize, const char *test_buf);
+int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf);
+int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
+	const char *ok_chars, const char *cancel_chars,
+	int flags, char *result_buf);
+int UI_add_info_string(UI *ui, const char *text);
+int UI_dup_info_string(UI *ui, const char *text);
+int UI_add_error_string(UI *ui, const char *text);
+int UI_dup_error_string(UI *ui, const char *text);
+
+/* These are the possible flags.  They can be or'ed together. */
+/* Use to have echoing of input */
+#define UI_INPUT_FLAG_ECHO		0x01
+/* Use a default password.  Where that password is found is completely
+   up to the application, it might for example be in the user data set
+   with UI_add_user_data().  It is not recommended to have more than
+   one input in each UI being marked with this flag, or the application
+   might get confused. */
+#define UI_INPUT_FLAG_DEFAULT_PWD	0x02
+
+/* The user of these routines may want to define flags of their own.  The core
+   UI won't look at those, but will pass them on to the method routines.  They
+   must use higher bits so they don't get confused with the UI bits above.
+   UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use.  A good
+   example of use is this:
+
+	#define MY_UI_FLAG1	(0x01 << UI_INPUT_FLAG_USER_BASE)
+
+*/
+#define UI_INPUT_FLAG_USER_BASE	16
+
+
+/* The following function helps construct a prompt.  object_desc is a
+   textual short description of the object, for example "pass phrase",
+   and object_name is the name of the object (might be a card name or
+   a file name.
+   The returned string shall always be allocated on the heap with
+   OPENSSL_malloc(), and need to be free'd with OPENSSL_free().
+
+   If the ui_method doesn't contain a pointer to a user-defined prompt
+   constructor, a default string is built, looking like this:
+
+	"Enter {object_desc} for {object_name}:"
+
+   So, if object_desc has the value "pass phrase" and object_name has
+   the value "foo.key", the resulting string is:
+
+	"Enter pass phrase for foo.key:"
+*/
+char *UI_construct_prompt(UI *ui_method,
+	const char *object_desc, const char *object_name);
+
+
+/* The following function is used to store a pointer to user-specific data.
+   Any previous such pointer will be returned and replaced.
+
+   For callback purposes, this function makes a lot more sense than using
+   ex_data, since the latter requires that different parts of OpenSSL or
+   applications share the same ex_data index.
+
+   Note that the UI_OpenSSL() method completely ignores the user data.
+   Other methods may not, however.  */
+void *UI_add_user_data(UI *ui, void *user_data);
+/* We need a user data retrieving function as well.  */
+void *UI_get0_user_data(UI *ui);
+
+/* Return the result associated with a prompt given with the index i. */
+const char *UI_get0_result(UI *ui, int i);
+
+/* When all strings have been added, process the whole thing. */
+int UI_process(UI *ui);
+
+/* Give a user interface parametrised control commands.  This can be used to
+   send down an integer, a data pointer or a function pointer, as well as
+   be used to get information from a UI. */
+int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f)(void));
+
+/* The commands */
+/* Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the
+   OpenSSL error stack before printing any info or added error messages and
+   before any prompting. */
+#define UI_CTRL_PRINT_ERRORS		1
+/* Check if a UI_process() is possible to do again with the same instance of
+   a user interface.  This makes UI_ctrl() return 1 if it is redoable, and 0
+   if not. */
+#define UI_CTRL_IS_REDOABLE		2
+
+
+/* Some methods may use extra data */
+#define UI_set_app_data(s,arg)         UI_set_ex_data(s,0,arg)
+#define UI_get_app_data(s)             UI_get_ex_data(s,0)
+int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int UI_set_ex_data(UI *r,int idx,void *arg);
+void *UI_get_ex_data(UI *r, int idx);
+
+/* Use specific methods instead of the built-in one */
+void UI_set_default_method(const UI_METHOD *meth);
+const UI_METHOD *UI_get_default_method(void);
+const UI_METHOD *UI_get_method(UI *ui);
+const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth);
+
+/* The method with all the built-in thingies */
+UI_METHOD *UI_OpenSSL(void);
+
+
+/* ---------- For method writers ---------- */
+/* A method contains a number of functions that implement the low level
+   of the User Interface.  The functions are:
+
+	an opener	This function starts a session, maybe by opening
+			a channel to a tty, or by opening a window.
+	a writer	This function is called to write a given string,
+			maybe to the tty, maybe as a field label in a
+			window.
+	a flusher	This function is called to flush everything that
+			has been output so far.  It can be used to actually
+			display a dialog box after it has been built.
+	a reader	This function is called to read a given prompt,
+			maybe from the tty, maybe from a field in a
+			window.  Note that it's called wth all string
+			structures, not only the prompt ones, so it must
+			check such things itself.
+	a closer	This function closes the session, maybe by closing
+			the channel to the tty, or closing the window.
+
+   All these functions are expected to return:
+
+	0	on error.
+	1	on success.
+	-1	on out-of-band events, for example if some prompting has
+		been canceled (by pressing Ctrl-C, for example).  This is
+		only checked when returned by the flusher or the reader.
+
+   The way this is used, the opener is first called, then the writer for all
+   strings, then the flusher, then the reader for all strings and finally the
+   closer.  Note that if you want to prompt from a terminal or other command
+   line interface, the best is to have the reader also write the prompts
+   instead of having the writer do it.  If you want to prompt from a dialog
+   box, the writer can be used to build up the contents of the box, and the
+   flusher to actually display the box and run the event loop until all data
+   has been given, after which the reader only grabs the given data and puts
+   them back into the UI strings.
+
+   All method functions take a UI as argument.  Additionally, the writer and
+   the reader take a UI_STRING.
+*/
+
+/* The UI_STRING type is the data structure that contains all the needed info
+   about a string or a prompt, including test data for a verification prompt.
+*/
+DECLARE_STACK_OF(UI_STRING)
+typedef struct ui_string_st UI_STRING;
+
+/* The different types of strings that are currently supported.
+   This is only needed by method authors. */
+enum UI_string_types
+	{
+	UIT_NONE=0,
+	UIT_PROMPT,		/* Prompt for a string */
+	UIT_VERIFY,		/* Prompt for a string and verify */
+	UIT_BOOLEAN,		/* Prompt for a yes/no response */
+	UIT_INFO,		/* Send info to the user */
+	UIT_ERROR		/* Send an error message to the user */
+	};
+
+/* Create and manipulate methods */
+UI_METHOD *UI_create_method(char *name);
+void UI_destroy_method(UI_METHOD *ui_method);
+int UI_method_set_opener(UI_METHOD *method, int (*opener)(UI *ui));
+int UI_method_set_writer(UI_METHOD *method, int (*writer)(UI *ui, UI_STRING *uis));
+int UI_method_set_flusher(UI_METHOD *method, int (*flusher)(UI *ui));
+int UI_method_set_reader(UI_METHOD *method, int (*reader)(UI *ui, UI_STRING *uis));
+int UI_method_set_closer(UI_METHOD *method, int (*closer)(UI *ui));
+int (*UI_method_get_opener(UI_METHOD *method))(UI*);
+int (*UI_method_get_writer(UI_METHOD *method))(UI*,UI_STRING*);
+int (*UI_method_get_flusher(UI_METHOD *method))(UI*);
+int (*UI_method_get_reader(UI_METHOD *method))(UI*,UI_STRING*);
+int (*UI_method_get_closer(UI_METHOD *method))(UI*);
+
+/* The following functions are helpers for method writers to access relevant
+   data from a UI_STRING. */
+
+/* Return type of the UI_STRING */
+enum UI_string_types UI_get_string_type(UI_STRING *uis);
+/* Return input flags of the UI_STRING */
+int UI_get_input_flags(UI_STRING *uis);
+/* Return the actual string to output (the prompt, info or error) */
+const char *UI_get0_output_string(UI_STRING *uis);
+/* Return the optional action string to output (the boolean promtp instruction) */
+const char *UI_get0_action_string(UI_STRING *uis);
+/* Return the result of a prompt */
+const char *UI_get0_result_string(UI_STRING *uis);
+/* Return the string to test the result against.  Only useful with verifies. */
+const char *UI_get0_test_string(UI_STRING *uis);
+/* Return the required minimum size of the result */
+int UI_get_result_minsize(UI_STRING *uis);
+/* Return the required maximum size of the result */
+int UI_get_result_maxsize(UI_STRING *uis);
+/* Set the result of a UI_STRING. */
+int UI_set_result(UI *ui, UI_STRING *uis, const char *result);
+
+
+/* A couple of popular utility functions */
+int UI_UTIL_read_pw_string(char *buf,int length,const char *prompt,int verify);
+int UI_UTIL_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
+
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_UI_strings(void);
+
+/* Error codes for the UI functions. */
+
+/* Function codes. */
+#define UI_F_GENERAL_ALLOCATE_BOOLEAN			 108
+#define UI_F_GENERAL_ALLOCATE_PROMPT			 109
+#define UI_F_GENERAL_ALLOCATE_STRING			 100
+#define UI_F_UI_CTRL					 111
+#define UI_F_UI_DUP_ERROR_STRING			 101
+#define UI_F_UI_DUP_INFO_STRING				 102
+#define UI_F_UI_DUP_INPUT_BOOLEAN			 110
+#define UI_F_UI_DUP_INPUT_STRING			 103
+#define UI_F_UI_DUP_VERIFY_STRING			 106
+#define UI_F_UI_GET0_RESULT				 107
+#define UI_F_UI_NEW_METHOD				 104
+#define UI_F_UI_SET_RESULT				 105
+
+/* Reason codes. */
+#define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS		 104
+#define UI_R_INDEX_TOO_LARGE				 102
+#define UI_R_INDEX_TOO_SMALL				 103
+#define UI_R_NO_RESULT_BUFFER				 105
+#define UI_R_RESULT_TOO_LARGE				 100
+#define UI_R_RESULT_TOO_SMALL				 101
+#define UI_R_UNKNOWN_CONTROL_COMMAND			 106
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ui_compat.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ui_compat.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/ui_compat.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,83 @@
+/* crypto/ui/ui.h -*- mode:C; c-file-style: "eay" -*- */
+/* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
+ * project 2001.
+ */
+/* ====================================================================
+ * Copyright (c) 2001 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#ifndef HEADER_UI_COMPAT_H
+#define HEADER_UI_COMPAT_H
+
+#include <openssl/opensslconf.h>
+#include <openssl/ui.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* The following functions were previously part of the DES section,
+   and are provided here for backward compatibility reasons. */
+
+#define des_read_pw_string(b,l,p,v) \
+	_ossl_old_des_read_pw_string((b),(l),(p),(v))
+#define des_read_pw(b,bf,s,p,v) \
+	_ossl_old_des_read_pw((b),(bf),(s),(p),(v))
+
+int _ossl_old_des_read_pw_string(char *buf,int length,const char *prompt,int verify);
+int _ossl_old_des_read_pw(char *buf,char *buff,int size,const char *prompt,int verify);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/x509.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/x509.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/x509.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,1340 @@
+/* crypto/x509/x509.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
+ * ECDH support in OpenSSL originally developed by 
+ * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
+ */
+
+#ifndef HEADER_X509_H
+#define HEADER_X509_H
+
+#include <openssl/e_os2.h>
+#include <openssl/symhacks.h>
+#ifndef OPENSSL_NO_BUFFER
+#include <openssl/buffer.h>
+#endif
+#ifndef OPENSSL_NO_EVP
+#include <openssl/evp.h>
+#endif
+#ifndef OPENSSL_NO_BIO
+#include <openssl/bio.h>
+#endif
+#include <openssl/stack.h>
+#include <openssl/asn1.h>
+#include <openssl/safestack.h>
+
+#ifndef OPENSSL_NO_EC
+#include <openssl/ec.h>
+#endif
+
+#ifndef OPENSSL_NO_ECDSA
+#include <openssl/ecdsa.h>
+#endif
+
+#ifndef OPENSSL_NO_ECDH
+#include <openssl/ecdh.h>
+#endif
+
+#ifndef OPENSSL_NO_DEPRECATED
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#endif
+
+#ifndef OPENSSL_NO_SHA
+#include <openssl/sha.h>
+#endif
+#include <openssl/ossl_typ.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+/* Under Win32 these are defined in wincrypt.h */
+#undef X509_NAME
+#undef X509_CERT_PAIR
+#endif
+
+#define X509_FILETYPE_PEM	1
+#define X509_FILETYPE_ASN1	2
+#define X509_FILETYPE_DEFAULT	3
+
+#define X509v3_KU_DIGITAL_SIGNATURE	0x0080
+#define X509v3_KU_NON_REPUDIATION	0x0040
+#define X509v3_KU_KEY_ENCIPHERMENT	0x0020
+#define X509v3_KU_DATA_ENCIPHERMENT	0x0010
+#define X509v3_KU_KEY_AGREEMENT		0x0008
+#define X509v3_KU_KEY_CERT_SIGN		0x0004
+#define X509v3_KU_CRL_SIGN		0x0002
+#define X509v3_KU_ENCIPHER_ONLY		0x0001
+#define X509v3_KU_DECIPHER_ONLY		0x8000
+#define X509v3_KU_UNDEF			0xffff
+
+typedef struct X509_objects_st
+	{
+	int nid;
+	int (*a2i)(void);
+	int (*i2a)(void);
+	} X509_OBJECTS;
+
+struct X509_algor_st
+	{
+	ASN1_OBJECT *algorithm;
+	ASN1_TYPE *parameter;
+	} /* X509_ALGOR */;
+
+DECLARE_STACK_OF(X509_ALGOR)
+DECLARE_ASN1_SET_OF(X509_ALGOR)
+
+typedef struct X509_val_st
+	{
+	ASN1_TIME *notBefore;
+	ASN1_TIME *notAfter;
+	} X509_VAL;
+
+typedef struct X509_pubkey_st
+	{
+	X509_ALGOR *algor;
+	ASN1_BIT_STRING *public_key;
+	EVP_PKEY *pkey;
+	} X509_PUBKEY;
+
+typedef struct X509_sig_st
+	{
+	X509_ALGOR *algor;
+	ASN1_OCTET_STRING *digest;
+	} X509_SIG;
+
+typedef struct X509_name_entry_st
+	{
+	ASN1_OBJECT *object;
+	ASN1_STRING *value;
+	int set;
+	int size; 	/* temp variable */
+	} X509_NAME_ENTRY;
+
+DECLARE_STACK_OF(X509_NAME_ENTRY)
+DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
+
+/* we always keep X509_NAMEs in 2 forms. */
+struct X509_name_st
+	{
+	STACK_OF(X509_NAME_ENTRY) *entries;
+	int modified;	/* true if 'bytes' needs to be built */
+#ifndef OPENSSL_NO_BUFFER
+	BUF_MEM *bytes;
+#else
+	char *bytes;
+#endif
+	unsigned long hash; /* Keep the hash around for lookups */
+	} /* X509_NAME */;
+
+DECLARE_STACK_OF(X509_NAME)
+
+#define X509_EX_V_NETSCAPE_HACK		0x8000
+#define X509_EX_V_INIT			0x0001
+typedef struct X509_extension_st
+	{
+	ASN1_OBJECT *object;
+	ASN1_BOOLEAN critical;
+	ASN1_OCTET_STRING *value;
+	} X509_EXTENSION;
+
+DECLARE_STACK_OF(X509_EXTENSION)
+DECLARE_ASN1_SET_OF(X509_EXTENSION)
+
+/* a sequence of these are used */
+typedef struct x509_attributes_st
+	{
+	ASN1_OBJECT *object;
+	int single; /* 0 for a set, 1 for a single item (which is wrong) */
+	union	{
+		char		*ptr;
+/* 0 */		STACK_OF(ASN1_TYPE) *set;
+/* 1 */		ASN1_TYPE	*single;
+		} value;
+	} X509_ATTRIBUTE;
+
+DECLARE_STACK_OF(X509_ATTRIBUTE)
+DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
+
+
+typedef struct X509_req_info_st
+	{
+	ASN1_ENCODING enc;
+	ASN1_INTEGER *version;
+	X509_NAME *subject;
+	X509_PUBKEY *pubkey;
+	/*  d=2 hl=2 l=  0 cons: cont: 00 */
+	STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
+	} X509_REQ_INFO;
+
+typedef struct X509_req_st
+	{
+	X509_REQ_INFO *req_info;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int references;
+	} X509_REQ;
+
+typedef struct x509_cinf_st
+	{
+	ASN1_INTEGER *version;		/* [ 0 ] default of v1 */
+	ASN1_INTEGER *serialNumber;
+	X509_ALGOR *signature;
+	X509_NAME *issuer;
+	X509_VAL *validity;
+	X509_NAME *subject;
+	X509_PUBKEY *key;
+	ASN1_BIT_STRING *issuerUID;		/* [ 1 ] optional in v2 */
+	ASN1_BIT_STRING *subjectUID;		/* [ 2 ] optional in v2 */
+	STACK_OF(X509_EXTENSION) *extensions;	/* [ 3 ] optional in v3 */
+	} X509_CINF;
+
+/* This stuff is certificate "auxiliary info"
+ * it contains details which are useful in certificate
+ * stores and databases. When used this is tagged onto
+ * the end of the certificate itself
+ */
+
+typedef struct x509_cert_aux_st
+	{
+	STACK_OF(ASN1_OBJECT) *trust;		/* trusted uses */
+	STACK_OF(ASN1_OBJECT) *reject;		/* rejected uses */
+	ASN1_UTF8STRING *alias;			/* "friendly name" */
+	ASN1_OCTET_STRING *keyid;		/* key id of private key */
+	STACK_OF(X509_ALGOR) *other;		/* other unspecified info */
+	} X509_CERT_AUX;
+
+struct x509_st
+	{
+	X509_CINF *cert_info;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int valid;
+	int references;
+	char *name;
+	CRYPTO_EX_DATA ex_data;
+	/* These contain copies of various extension values */
+	long ex_pathlen;
+	long ex_pcpathlen;
+	unsigned long ex_flags;
+	unsigned long ex_kusage;
+	unsigned long ex_xkusage;
+	unsigned long ex_nscert;
+	ASN1_OCTET_STRING *skid;
+	struct AUTHORITY_KEYID_st *akid;
+	X509_POLICY_CACHE *policy_cache;
+#ifndef OPENSSL_NO_SHA
+	unsigned char sha1_hash[SHA_DIGEST_LENGTH];
+#endif
+	X509_CERT_AUX *aux;
+	} /* X509 */;
+
+DECLARE_STACK_OF(X509)
+DECLARE_ASN1_SET_OF(X509)
+
+/* This is used for a table of trust checking functions */
+
+typedef struct x509_trust_st {
+	int trust;
+	int flags;
+	int (*check_trust)(struct x509_trust_st *, X509 *, int);
+	char *name;
+	int arg1;
+	void *arg2;
+} X509_TRUST;
+
+DECLARE_STACK_OF(X509_TRUST)
+
+typedef struct x509_cert_pair_st {
+	X509 *forward;
+	X509 *reverse;
+} X509_CERT_PAIR;
+
+/* standard trust ids */
+
+#define X509_TRUST_DEFAULT	-1	/* Only valid in purpose settings */
+
+#define X509_TRUST_COMPAT	1
+#define X509_TRUST_SSL_CLIENT	2
+#define X509_TRUST_SSL_SERVER	3
+#define X509_TRUST_EMAIL	4
+#define X509_TRUST_OBJECT_SIGN	5
+#define X509_TRUST_OCSP_SIGN	6
+#define X509_TRUST_OCSP_REQUEST	7
+
+/* Keep these up to date! */
+#define X509_TRUST_MIN		1
+#define X509_TRUST_MAX		7
+
+
+/* trust_flags values */
+#define	X509_TRUST_DYNAMIC 	1
+#define	X509_TRUST_DYNAMIC_NAME	2
+
+/* check_trust return codes */
+
+#define X509_TRUST_TRUSTED	1
+#define X509_TRUST_REJECTED	2
+#define X509_TRUST_UNTRUSTED	3
+
+/* Flags for X509_print_ex() */
+
+#define	X509_FLAG_COMPAT		0
+#define	X509_FLAG_NO_HEADER		1L
+#define	X509_FLAG_NO_VERSION		(1L << 1)
+#define	X509_FLAG_NO_SERIAL		(1L << 2)
+#define	X509_FLAG_NO_SIGNAME		(1L << 3)
+#define	X509_FLAG_NO_ISSUER		(1L << 4)
+#define	X509_FLAG_NO_VALIDITY		(1L << 5)
+#define	X509_FLAG_NO_SUBJECT		(1L << 6)
+#define	X509_FLAG_NO_PUBKEY		(1L << 7)
+#define	X509_FLAG_NO_EXTENSIONS		(1L << 8)
+#define	X509_FLAG_NO_SIGDUMP		(1L << 9)
+#define	X509_FLAG_NO_AUX		(1L << 10)
+#define	X509_FLAG_NO_ATTRIBUTES		(1L << 11)
+
+/* Flags specific to X509_NAME_print_ex() */	
+
+/* The field separator information */
+
+#define XN_FLAG_SEP_MASK	(0xf << 16)
+
+#define XN_FLAG_COMPAT		0		/* Traditional SSLeay: use old X509_NAME_print */
+#define XN_FLAG_SEP_COMMA_PLUS	(1 << 16)	/* RFC2253 ,+ */
+#define XN_FLAG_SEP_CPLUS_SPC	(2 << 16)	/* ,+ spaced: more readable */
+#define XN_FLAG_SEP_SPLUS_SPC	(3 << 16)	/* ;+ spaced */
+#define XN_FLAG_SEP_MULTILINE	(4 << 16)	/* One line per field */
+
+#define XN_FLAG_DN_REV		(1 << 20)	/* Reverse DN order */
+
+/* How the field name is shown */
+
+#define XN_FLAG_FN_MASK		(0x3 << 21)
+
+#define XN_FLAG_FN_SN		0		/* Object short name */
+#define XN_FLAG_FN_LN		(1 << 21)	/* Object long name */
+#define XN_FLAG_FN_OID		(2 << 21)	/* Always use OIDs */
+#define XN_FLAG_FN_NONE		(3 << 21)	/* No field names */
+
+#define XN_FLAG_SPC_EQ		(1 << 23)	/* Put spaces round '=' */
+
+/* This determines if we dump fields we don't recognise:
+ * RFC2253 requires this.
+ */
+
+#define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
+
+#define XN_FLAG_FN_ALIGN	(1 << 25)	/* Align field names to 20 characters */
+
+/* Complete set of RFC2253 flags */
+
+#define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
+			XN_FLAG_SEP_COMMA_PLUS | \
+			XN_FLAG_DN_REV | \
+			XN_FLAG_FN_SN | \
+			XN_FLAG_DUMP_UNKNOWN_FIELDS)
+
+/* readable oneline form */
+
+#define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
+			ASN1_STRFLGS_ESC_QUOTE | \
+			XN_FLAG_SEP_CPLUS_SPC | \
+			XN_FLAG_SPC_EQ | \
+			XN_FLAG_FN_SN)
+
+/* readable multiline form */
+
+#define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
+			ASN1_STRFLGS_ESC_MSB | \
+			XN_FLAG_SEP_MULTILINE | \
+			XN_FLAG_SPC_EQ | \
+			XN_FLAG_FN_LN | \
+			XN_FLAG_FN_ALIGN)
+
+typedef struct X509_revoked_st
+	{
+	ASN1_INTEGER *serialNumber;
+	ASN1_TIME *revocationDate;
+	STACK_OF(X509_EXTENSION) /* optional */ *extensions;
+	int sequence; /* load sequence */
+	} X509_REVOKED;
+
+DECLARE_STACK_OF(X509_REVOKED)
+DECLARE_ASN1_SET_OF(X509_REVOKED)
+
+typedef struct X509_crl_info_st
+	{
+	ASN1_INTEGER *version;
+	X509_ALGOR *sig_alg;
+	X509_NAME *issuer;
+	ASN1_TIME *lastUpdate;
+	ASN1_TIME *nextUpdate;
+	STACK_OF(X509_REVOKED) *revoked;
+	STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
+	ASN1_ENCODING enc;
+	} X509_CRL_INFO;
+
+struct X509_crl_st
+	{
+	/* actual signature */
+	X509_CRL_INFO *crl;
+	X509_ALGOR *sig_alg;
+	ASN1_BIT_STRING *signature;
+	int references;
+	} /* X509_CRL */;
+
+DECLARE_STACK_OF(X509_CRL)
+DECLARE_ASN1_SET_OF(X509_CRL)
+
+typedef struct private_key_st
+	{
+	int version;
+	/* The PKCS#8 data types */
+	X509_ALGOR *enc_algor;
+	ASN1_OCTET_STRING *enc_pkey;	/* encrypted pub key */
+
+	/* When decrypted, the following will not be NULL */
+	EVP_PKEY *dec_pkey;
+
+	/* used to encrypt and decrypt */
+	int key_length;
+	char *key_data;
+	int key_free;	/* true if we should auto free key_data */
+
+	/* expanded version of 'enc_algor' */
+	EVP_CIPHER_INFO cipher;
+
+	int references;
+	} X509_PKEY;
+
+#ifndef OPENSSL_NO_EVP
+typedef struct X509_info_st
+	{
+	X509 *x509;
+	X509_CRL *crl;
+	X509_PKEY *x_pkey;
+
+	EVP_CIPHER_INFO enc_cipher;
+	int enc_len;
+	char *enc_data;
+
+	int references;
+	} X509_INFO;
+
+DECLARE_STACK_OF(X509_INFO)
+#endif
+
+/* The next 2 structures and their 8 routines were sent to me by
+ * Pat Richard <patr@x509.com> and are used to manipulate
+ * Netscapes spki structures - useful if you are writing a CA web page
+ */
+typedef struct Netscape_spkac_st
+	{
+	X509_PUBKEY *pubkey;
+	ASN1_IA5STRING *challenge;	/* challenge sent in atlas >= PR2 */
+	} NETSCAPE_SPKAC;
+
+typedef struct Netscape_spki_st
+	{
+	NETSCAPE_SPKAC *spkac;	/* signed public key and challenge */
+	X509_ALGOR *sig_algor;
+	ASN1_BIT_STRING *signature;
+	} NETSCAPE_SPKI;
+
+/* Netscape certificate sequence structure */
+typedef struct Netscape_certificate_sequence
+	{
+	ASN1_OBJECT *type;
+	STACK_OF(X509) *certs;
+	} NETSCAPE_CERT_SEQUENCE;
+
+/* Unused (and iv length is wrong)
+typedef struct CBCParameter_st
+	{
+	unsigned char iv[8];
+	} CBC_PARAM;
+*/
+
+/* Password based encryption structure */
+
+typedef struct PBEPARAM_st {
+ASN1_OCTET_STRING *salt;
+ASN1_INTEGER *iter;
+} PBEPARAM;
+
+/* Password based encryption V2 structures */
+
+typedef struct PBE2PARAM_st {
+X509_ALGOR *keyfunc;
+X509_ALGOR *encryption;
+} PBE2PARAM;
+
+typedef struct PBKDF2PARAM_st {
+ASN1_TYPE *salt;	/* Usually OCTET STRING but could be anything */
+ASN1_INTEGER *iter;
+ASN1_INTEGER *keylength;
+X509_ALGOR *prf;
+} PBKDF2PARAM;
+
+
+/* PKCS#8 private key info structure */
+
+typedef struct pkcs8_priv_key_info_st
+        {
+        int broken;     /* Flag for various broken formats */
+#define PKCS8_OK		0
+#define PKCS8_NO_OCTET		1
+#define PKCS8_EMBEDDED_PARAM	2
+#define PKCS8_NS_DB		3
+        ASN1_INTEGER *version;
+        X509_ALGOR *pkeyalg;
+        ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */
+        STACK_OF(X509_ATTRIBUTE) *attributes;
+        } PKCS8_PRIV_KEY_INFO;
+
+#ifdef  __cplusplus
+}
+#endif
+
+#include <openssl/x509_vfy.h>
+#include <openssl/pkcs7.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+#ifdef SSLEAY_MACROS
+#define X509_verify(a,r) ASN1_verify((int (*)())i2d_X509_CINF,a->sig_alg,\
+	a->signature,(char *)a->cert_info,r)
+#define X509_REQ_verify(a,r) ASN1_verify((int (*)())i2d_X509_REQ_INFO, \
+	a->sig_alg,a->signature,(char *)a->req_info,r)
+#define X509_CRL_verify(a,r) ASN1_verify((int (*)())i2d_X509_CRL_INFO, \
+	a->sig_alg, a->signature,(char *)a->crl,r)
+
+#define X509_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_X509_CINF, x->cert_info->signature, \
+		x->sig_alg, x->signature, (char *)x->cert_info,pkey,md)
+#define X509_REQ_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_X509_REQ_INFO,x->sig_alg, NULL, \
+		x->signature, (char *)x->req_info,pkey,md)
+#define X509_CRL_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_X509_CRL_INFO,x->crl->sig_alg,x->sig_alg, \
+		x->signature, (char *)x->crl,pkey,md)
+#define NETSCAPE_SPKI_sign(x,pkey,md) \
+	ASN1_sign((int (*)())i2d_NETSCAPE_SPKAC, x->sig_algor,NULL, \
+		x->signature, (char *)x->spkac,pkey,md)
+
+#define X509_dup(x509) (X509 *)ASN1_dup((int (*)())i2d_X509, \
+		(char *(*)())d2i_X509,(char *)x509)
+#define X509_ATTRIBUTE_dup(xa) (X509_ATTRIBUTE *)ASN1_dup(\
+		(int (*)())i2d_X509_ATTRIBUTE, \
+		(char *(*)())d2i_X509_ATTRIBUTE,(char *)xa)
+#define X509_EXTENSION_dup(ex) (X509_EXTENSION *)ASN1_dup( \
+		(int (*)())i2d_X509_EXTENSION, \
+		(char *(*)())d2i_X509_EXTENSION,(char *)ex)
+#define d2i_X509_fp(fp,x509) (X509 *)ASN1_d2i_fp((char *(*)())X509_new, \
+		(char *(*)())d2i_X509, (fp),(unsigned char **)(x509))
+#define i2d_X509_fp(fp,x509) ASN1_i2d_fp(i2d_X509,fp,(unsigned char *)x509)
+#define d2i_X509_bio(bp,x509) (X509 *)ASN1_d2i_bio((char *(*)())X509_new, \
+		(char *(*)())d2i_X509, (bp),(unsigned char **)(x509))
+#define i2d_X509_bio(bp,x509) ASN1_i2d_bio(i2d_X509,bp,(unsigned char *)x509)
+
+#define X509_CRL_dup(crl) (X509_CRL *)ASN1_dup((int (*)())i2d_X509_CRL, \
+		(char *(*)())d2i_X509_CRL,(char *)crl)
+#define d2i_X509_CRL_fp(fp,crl) (X509_CRL *)ASN1_d2i_fp((char *(*)()) \
+		X509_CRL_new,(char *(*)())d2i_X509_CRL, (fp),\
+		(unsigned char **)(crl))
+#define i2d_X509_CRL_fp(fp,crl) ASN1_i2d_fp(i2d_X509_CRL,fp,\
+		(unsigned char *)crl)
+#define d2i_X509_CRL_bio(bp,crl) (X509_CRL *)ASN1_d2i_bio((char *(*)()) \
+		X509_CRL_new,(char *(*)())d2i_X509_CRL, (bp),\
+		(unsigned char **)(crl))
+#define i2d_X509_CRL_bio(bp,crl) ASN1_i2d_bio(i2d_X509_CRL,bp,\
+		(unsigned char *)crl)
+
+#define PKCS7_dup(p7) (PKCS7 *)ASN1_dup((int (*)())i2d_PKCS7, \
+		(char *(*)())d2i_PKCS7,(char *)p7)
+#define d2i_PKCS7_fp(fp,p7) (PKCS7 *)ASN1_d2i_fp((char *(*)()) \
+		PKCS7_new,(char *(*)())d2i_PKCS7, (fp),\
+		(unsigned char **)(p7))
+#define i2d_PKCS7_fp(fp,p7) ASN1_i2d_fp(i2d_PKCS7,fp,\
+		(unsigned char *)p7)
+#define d2i_PKCS7_bio(bp,p7) (PKCS7 *)ASN1_d2i_bio((char *(*)()) \
+		PKCS7_new,(char *(*)())d2i_PKCS7, (bp),\
+		(unsigned char **)(p7))
+#define i2d_PKCS7_bio(bp,p7) ASN1_i2d_bio(i2d_PKCS7,bp,\
+		(unsigned char *)p7)
+
+#define X509_REQ_dup(req) (X509_REQ *)ASN1_dup((int (*)())i2d_X509_REQ, \
+		(char *(*)())d2i_X509_REQ,(char *)req)
+#define d2i_X509_REQ_fp(fp,req) (X509_REQ *)ASN1_d2i_fp((char *(*)())\
+		X509_REQ_new, (char *(*)())d2i_X509_REQ, (fp),\
+		(unsigned char **)(req))
+#define i2d_X509_REQ_fp(fp,req) ASN1_i2d_fp(i2d_X509_REQ,fp,\
+		(unsigned char *)req)
+#define d2i_X509_REQ_bio(bp,req) (X509_REQ *)ASN1_d2i_bio((char *(*)())\
+		X509_REQ_new, (char *(*)())d2i_X509_REQ, (bp),\
+		(unsigned char **)(req))
+#define i2d_X509_REQ_bio(bp,req) ASN1_i2d_bio(i2d_X509_REQ,bp,\
+		(unsigned char *)req)
+
+#define RSAPublicKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPublicKey, \
+		(char *(*)())d2i_RSAPublicKey,(char *)rsa)
+#define RSAPrivateKey_dup(rsa) (RSA *)ASN1_dup((int (*)())i2d_RSAPrivateKey, \
+		(char *(*)())d2i_RSAPrivateKey,(char *)rsa)
+
+#define d2i_RSAPrivateKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPrivateKey, (fp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPrivateKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPrivateKey,fp, \
+		(unsigned char *)rsa)
+#define d2i_RSAPrivateKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPrivateKey, (bp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPrivateKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPrivateKey,bp, \
+		(unsigned char *)rsa)
+
+#define d2i_RSAPublicKey_fp(fp,rsa) (RSA *)ASN1_d2i_fp((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPublicKey, (fp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPublicKey_fp(fp,rsa) ASN1_i2d_fp(i2d_RSAPublicKey,fp, \
+		(unsigned char *)rsa)
+#define d2i_RSAPublicKey_bio(bp,rsa) (RSA *)ASN1_d2i_bio((char *(*)())\
+		RSA_new,(char *(*)())d2i_RSAPublicKey, (bp), \
+		(unsigned char **)(rsa))
+#define i2d_RSAPublicKey_bio(bp,rsa) ASN1_i2d_bio(i2d_RSAPublicKey,bp, \
+		(unsigned char *)rsa)
+
+#define d2i_DSAPrivateKey_fp(fp,dsa) (DSA *)ASN1_d2i_fp((char *(*)())\
+		DSA_new,(char *(*)())d2i_DSAPrivateKey, (fp), \
+		(unsigned char **)(dsa))
+#define i2d_DSAPrivateKey_fp(fp,dsa) ASN1_i2d_fp(i2d_DSAPrivateKey,fp, \
+		(unsigned char *)dsa)
+#define d2i_DSAPrivateKey_bio(bp,dsa) (DSA *)ASN1_d2i_bio((char *(*)())\
+		DSA_new,(char *(*)())d2i_DSAPrivateKey, (bp), \
+		(unsigned char **)(dsa))
+#define i2d_DSAPrivateKey_bio(bp,dsa) ASN1_i2d_bio(i2d_DSAPrivateKey,bp, \
+		(unsigned char *)dsa)
+
+#define d2i_ECPrivateKey_fp(fp,ecdsa) (EC_KEY *)ASN1_d2i_fp((char *(*)())\
+		EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (fp), \
+		(unsigned char **)(ecdsa))
+#define i2d_ECPrivateKey_fp(fp,ecdsa) ASN1_i2d_fp(i2d_ECPrivateKey,fp, \
+		(unsigned char *)ecdsa)
+#define d2i_ECPrivateKey_bio(bp,ecdsa) (EC_KEY *)ASN1_d2i_bio((char *(*)())\
+		EC_KEY_new,(char *(*)())d2i_ECPrivateKey, (bp), \
+		(unsigned char **)(ecdsa))
+#define i2d_ECPrivateKey_bio(bp,ecdsa) ASN1_i2d_bio(i2d_ECPrivateKey,bp, \
+		(unsigned char *)ecdsa)
+
+#define X509_ALGOR_dup(xn) (X509_ALGOR *)ASN1_dup((int (*)())i2d_X509_ALGOR,\
+		(char *(*)())d2i_X509_ALGOR,(char *)xn)
+
+#define X509_NAME_dup(xn) (X509_NAME *)ASN1_dup((int (*)())i2d_X509_NAME, \
+		(char *(*)())d2i_X509_NAME,(char *)xn)
+#define X509_NAME_ENTRY_dup(ne) (X509_NAME_ENTRY *)ASN1_dup( \
+		(int (*)())i2d_X509_NAME_ENTRY, \
+		(char *(*)())d2i_X509_NAME_ENTRY,\
+		(char *)ne)
+
+#define X509_digest(data,type,md,len) \
+	ASN1_digest((int (*)())i2d_X509,type,(char *)data,md,len)
+#define X509_NAME_digest(data,type,md,len) \
+	ASN1_digest((int (*)())i2d_X509_NAME,type,(char *)data,md,len)
+#ifndef PKCS7_ISSUER_AND_SERIAL_digest
+#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
+	ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
+		(char *)data,md,len)
+#endif
+#endif
+
+#define X509_EXT_PACK_UNKNOWN	1
+#define X509_EXT_PACK_STRING	2
+
+#define		X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
+/* #define	X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
+#define		X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
+#define		X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
+#define		X509_extract_key(x)	X509_get_pubkey(x) /*****/
+#define		X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
+#define		X509_REQ_get_subject_name(x) ((x)->req_info->subject)
+#define		X509_REQ_extract_key(a)	X509_REQ_get_pubkey(a)
+#define		X509_name_cmp(a,b)	X509_NAME_cmp((a),(b))
+#define		X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
+
+#define		X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
+#define 	X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
+#define 	X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
+#define		X509_CRL_get_issuer(x) ((x)->crl->issuer)
+#define		X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
+
+/* This one is only used so that a binary form can output, as in
+ * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) */
+#define 	X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
+
+
+const char *X509_verify_cert_error_string(long n);
+
+#ifndef SSLEAY_MACROS
+#ifndef OPENSSL_NO_EVP
+int X509_verify(X509 *a, EVP_PKEY *r);
+
+int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
+int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
+
+NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len);
+char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
+EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
+int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
+
+int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
+
+int X509_signature_print(BIO *bp,X509_ALGOR *alg, ASN1_STRING *sig);
+
+int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
+int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
+int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
+
+int X509_pubkey_digest(const X509 *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_digest(const X509 *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type,
+		unsigned char *md, unsigned int *len);
+#endif
+
+#ifndef OPENSSL_NO_FP_API
+X509 *d2i_X509_fp(FILE *fp, X509 **x509);
+int i2d_X509_fp(FILE *fp,X509 *x509);
+X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl);
+int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req);
+int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req);
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa);
+int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa);
+RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa);
+int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa);
+RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa);
+int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
+int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
+int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
+#endif
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
+int   i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
+int   i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
+#endif
+X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8);
+int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
+						PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
+int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
+int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+X509 *d2i_X509_bio(BIO *bp,X509 **x509);
+int i2d_X509_bio(BIO *bp,X509 *x509);
+X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl);
+int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl);
+X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req);
+int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req);
+#ifndef OPENSSL_NO_RSA
+RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa);
+int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa);
+RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa);
+int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa);
+RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa);
+int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa);
+#endif
+#ifndef OPENSSL_NO_DSA
+DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
+int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
+DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
+int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
+#endif
+#ifndef OPENSSL_NO_EC
+EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
+int   i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
+EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
+int   i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
+#endif
+X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8);
+int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8);
+PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
+						PKCS8_PRIV_KEY_INFO **p8inf);
+int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf);
+int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
+int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
+int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
+EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
+#endif
+
+X509 *X509_dup(X509 *x509);
+X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
+X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
+X509_CRL *X509_CRL_dup(X509_CRL *crl);
+X509_REQ *X509_REQ_dup(X509_REQ *req);
+X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
+X509_NAME *X509_NAME_dup(X509_NAME *xn);
+X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
+
+#endif /* !SSLEAY_MACROS */
+
+int		X509_cmp_time(ASN1_TIME *s, time_t *t);
+int		X509_cmp_current_time(ASN1_TIME *s);
+ASN1_TIME *	X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
+ASN1_TIME *	X509_gmtime_adj(ASN1_TIME *s, long adj);
+
+const char *	X509_get_default_cert_area(void );
+const char *	X509_get_default_cert_dir(void );
+const char *	X509_get_default_cert_file(void );
+const char *	X509_get_default_cert_dir_env(void );
+const char *	X509_get_default_cert_file_env(void );
+const char *	X509_get_default_private_dir(void );
+
+X509_REQ *	X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
+X509 *		X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey);
+
+DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
+DECLARE_ASN1_FUNCTIONS(X509_VAL)
+
+DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
+
+int		X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_PUBKEY_get(X509_PUBKEY *key);
+int		X509_get_pubkey_parameters(EVP_PKEY *pkey,
+					   STACK_OF(X509) *chain);
+int		i2d_PUBKEY(EVP_PKEY *a,unsigned char **pp);
+EVP_PKEY *	d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp,
+			long length);
+#ifndef OPENSSL_NO_RSA
+int		i2d_RSA_PUBKEY(RSA *a,unsigned char **pp);
+RSA *		d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp,
+			long length);
+#endif
+#ifndef OPENSSL_NO_DSA
+int		i2d_DSA_PUBKEY(DSA *a,unsigned char **pp);
+DSA *		d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp,
+			long length);
+#endif
+#ifndef OPENSSL_NO_EC
+int		i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
+EC_KEY 		*d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp,
+			long length);
+#endif
+
+DECLARE_ASN1_FUNCTIONS(X509_SIG)
+DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_REQ)
+
+DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
+X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
+
+DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
+
+DECLARE_ASN1_FUNCTIONS(X509_NAME)
+
+int		X509_NAME_set(X509_NAME **xn, X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(X509_CINF)
+
+DECLARE_ASN1_FUNCTIONS(X509)
+DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
+
+DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
+
+int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int X509_set_ex_data(X509 *r, int idx, void *arg);
+void *X509_get_ex_data(X509 *r, int idx);
+int		i2d_X509_AUX(X509 *a,unsigned char **pp);
+X509 *		d2i_X509_AUX(X509 **a,const unsigned char **pp,long length);
+
+int X509_alias_set1(X509 *x, unsigned char *name, int len);
+int X509_keyid_set1(X509 *x, unsigned char *id, int len);
+unsigned char * X509_alias_get0(X509 *x, int *len);
+unsigned char * X509_keyid_get0(X509 *x, int *len);
+int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int);
+int X509_TRUST_set(int *t, int trust);
+int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
+int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
+void X509_trust_clear(X509 *x);
+void X509_reject_clear(X509 *x);
+
+DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
+DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
+DECLARE_ASN1_FUNCTIONS(X509_CRL)
+
+int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
+
+X509_PKEY *	X509_PKEY_new(void );
+void		X509_PKEY_free(X509_PKEY *a);
+int		i2d_X509_PKEY(X509_PKEY *a,unsigned char **pp);
+X509_PKEY *	d2i_X509_PKEY(X509_PKEY **a,const unsigned char **pp,long length);
+
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
+DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
+
+#ifndef OPENSSL_NO_EVP
+X509_INFO *	X509_INFO_new(void);
+void		X509_INFO_free(X509_INFO *a);
+char *		X509_NAME_oneline(X509_NAME *a,char *buf,int size);
+
+int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
+		ASN1_BIT_STRING *signature,char *data,EVP_PKEY *pkey);
+
+int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data,
+		unsigned char *md,unsigned int *len);
+
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
+	      X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
+	      char *data,EVP_PKEY *pkey, const EVP_MD *type);
+
+int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data,
+	unsigned char *md,unsigned int *len);
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
+	ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey);
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+	ASN1_BIT_STRING *signature,
+	void *data, EVP_PKEY *pkey, const EVP_MD *type);
+#endif
+
+int 		X509_set_version(X509 *x,long version);
+int 		X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
+ASN1_INTEGER *	X509_get_serialNumber(X509 *x);
+int 		X509_set_issuer_name(X509 *x, X509_NAME *name);
+X509_NAME *	X509_get_issuer_name(X509 *a);
+int 		X509_set_subject_name(X509 *x, X509_NAME *name);
+X509_NAME *	X509_get_subject_name(X509 *a);
+int 		X509_set_notBefore(X509 *x, ASN1_TIME *tm);
+int 		X509_set_notAfter(X509 *x, ASN1_TIME *tm);
+int 		X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_get_pubkey(X509 *x);
+ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x);
+int		X509_certificate_type(X509 *x,EVP_PKEY *pubkey /* optional */);
+
+int		X509_REQ_set_version(X509_REQ *x,long version);
+int		X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name);
+int		X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
+EVP_PKEY *	X509_REQ_get_pubkey(X509_REQ *req);
+int		X509_REQ_extension_nid(int nid);
+int *		X509_REQ_get_extension_nids(void);
+void		X509_REQ_set_extension_nids(int *nids);
+STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
+int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
+				int nid);
+int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
+int X509_REQ_get_attr_count(const X509_REQ *req);
+int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid,
+			  int lastpos);
+int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
+X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
+int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
+int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_NID(X509_REQ *req,
+			int nid, int type,
+			const unsigned char *bytes, int len);
+int X509_REQ_add1_attr_by_txt(X509_REQ *req,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len);
+
+int X509_CRL_set_version(X509_CRL *x, long version);
+int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
+int X509_CRL_set_lastUpdate(X509_CRL *x, ASN1_TIME *tm);
+int X509_CRL_set_nextUpdate(X509_CRL *x, ASN1_TIME *tm);
+int X509_CRL_sort(X509_CRL *crl);
+
+int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
+int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
+
+int		X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey);
+
+int		X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
+
+int		X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
+unsigned long	X509_issuer_and_serial_hash(X509 *a);
+
+int		X509_issuer_name_cmp(const X509 *a, const X509 *b);
+unsigned long	X509_issuer_name_hash(X509 *a);
+
+int		X509_subject_name_cmp(const X509 *a, const X509 *b);
+unsigned long	X509_subject_name_hash(X509 *x);
+
+int		X509_cmp(const X509 *a, const X509 *b);
+int		X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
+unsigned long	X509_NAME_hash(X509_NAME *x);
+
+int		X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
+#ifndef OPENSSL_NO_FP_API
+int		X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
+int		X509_print_fp(FILE *bp,X509 *x);
+int		X509_CRL_print_fp(FILE *bp,X509_CRL *x);
+int		X509_REQ_print_fp(FILE *bp,X509_REQ *req);
+int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags);
+#endif
+
+#ifndef OPENSSL_NO_BIO
+int		X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
+int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags);
+int		X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag);
+int		X509_print(BIO *bp,X509 *x);
+int		X509_ocspid_print(BIO *bp,X509 *x);
+int		X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent);
+int		X509_CRL_print(BIO *bp,X509_CRL *x);
+int		X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag);
+int		X509_REQ_print(BIO *bp,X509_REQ *req);
+#endif
+
+int 		X509_NAME_entry_count(X509_NAME *name);
+int 		X509_NAME_get_text_by_NID(X509_NAME *name, int nid,
+			char *buf,int len);
+int		X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
+			char *buf,int len);
+
+/* NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
+ * lastpos, search after that position on. */
+int 		X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos);
+int 		X509_NAME_get_index_by_OBJ(X509_NAME *name,ASN1_OBJECT *obj,
+			int lastpos);
+X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
+X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
+int 		X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne,
+			int loc, int set);
+int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
+			unsigned char *bytes, int len, int loc, int set);
+int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
+			unsigned char *bytes, int len, int loc, int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
+		const char *field, int type, const unsigned char *bytes, int len);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
+			int type,unsigned char *bytes, int len);
+int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
+			const unsigned char *bytes, int len, int loc, int set);
+X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
+			ASN1_OBJECT *obj, int type,const unsigned char *bytes,
+			int len);
+int 		X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne,
+			ASN1_OBJECT *obj);
+int 		X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
+			const unsigned char *bytes, int len);
+ASN1_OBJECT *	X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
+ASN1_STRING *	X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
+
+int		X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
+int		X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
+				      int nid, int lastpos);
+int		X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
+				      ASN1_OBJECT *obj,int lastpos);
+int		X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
+					   int crit, int lastpos);
+X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
+X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
+STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
+					 X509_EXTENSION *ex, int loc);
+
+int		X509_get_ext_count(X509 *x);
+int		X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
+int		X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
+X509_EXTENSION *X509_get_ext(X509 *x, int loc);
+X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
+int		X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
+void	*	X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
+int		X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
+							unsigned long flags);
+
+int		X509_CRL_get_ext_count(X509_CRL *x);
+int		X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
+int		X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
+X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
+X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
+int		X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
+void	*	X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
+int		X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
+							unsigned long flags);
+
+int		X509_REVOKED_get_ext_count(X509_REVOKED *x);
+int		X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
+int		X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos);
+int		X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
+X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
+X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
+int		X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
+void	*	X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
+int		X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
+							unsigned long flags);
+
+X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
+			int nid, int crit, ASN1_OCTET_STRING *data);
+X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
+			ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data);
+int		X509_EXTENSION_set_object(X509_EXTENSION *ex,ASN1_OBJECT *obj);
+int		X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
+int		X509_EXTENSION_set_data(X509_EXTENSION *ex,
+			ASN1_OCTET_STRING *data);
+ASN1_OBJECT *	X509_EXTENSION_get_object(X509_EXTENSION *ex);
+ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
+int		X509_EXTENSION_get_critical(X509_EXTENSION *ex);
+
+int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
+int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
+			  int lastpos);
+int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
+X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
+					 X509_ATTRIBUTE *attr);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) **x,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x,
+			int nid, int type,
+			const unsigned char *bytes, int len);
+STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) **x,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
+	     int atrtype, const void *data, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
+	     const ASN1_OBJECT *obj, int atrtype, const void *data, int len);
+X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
+		const char *atrname, int type, const unsigned char *bytes, int len);
+int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
+int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len);
+void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
+					int atrtype, void *data);
+int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
+ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
+ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
+
+int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
+int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid,
+			  int lastpos);
+int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
+			  int lastpos);
+X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
+X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
+int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
+int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
+			const ASN1_OBJECT *obj, int type,
+			const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
+			int nid, int type,
+			const unsigned char *bytes, int len);
+int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
+			const char *attrname, int type,
+			const unsigned char *bytes, int len);
+
+int		X509_verify_cert(X509_STORE_CTX *ctx);
+
+/* lookup a cert from a X509 STACK */
+X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name,
+				     ASN1_INTEGER *serial);
+X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name);
+
+DECLARE_ASN1_FUNCTIONS(PBEPARAM)
+DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
+DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
+
+X509_ALGOR *PKCS5_pbe_set(int alg, int iter, unsigned char *salt, int saltlen);
+X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
+					 unsigned char *salt, int saltlen);
+
+/* PKCS#8 utilities */
+
+DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
+
+EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
+PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
+PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
+
+int X509_check_trust(X509 *x, int id, int flags);
+int X509_TRUST_get_count(void);
+X509_TRUST * X509_TRUST_get0(int idx);
+int X509_TRUST_get_by_id(int id);
+int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
+					char *name, int arg1, void *arg2);
+void X509_TRUST_cleanup(void);
+int X509_TRUST_get_flags(X509_TRUST *xp);
+char *X509_TRUST_get0_name(X509_TRUST *xp);
+int X509_TRUST_get_trust(X509_TRUST *xp);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_X509_strings(void);
+
+/* Error codes for the X509 functions. */
+
+/* Function codes. */
+#define X509_F_ADD_CERT_DIR				 100
+#define X509_F_BY_FILE_CTRL				 101
+#define X509_F_CHECK_POLICY				 145
+#define X509_F_DIR_CTRL					 102
+#define X509_F_GET_CERT_BY_SUBJECT			 103
+#define X509_F_NETSCAPE_SPKI_B64_DECODE			 129
+#define X509_F_NETSCAPE_SPKI_B64_ENCODE			 130
+#define X509_F_X509AT_ADD1_ATTR				 135
+#define X509_F_X509V3_ADD_EXT				 104
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_NID		 136
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ		 137
+#define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT		 140
+#define X509_F_X509_ATTRIBUTE_GET0_DATA			 139
+#define X509_F_X509_ATTRIBUTE_SET1_DATA			 138
+#define X509_F_X509_CHECK_PRIVATE_KEY			 128
+#define X509_F_X509_CRL_PRINT_FP			 147
+#define X509_F_X509_EXTENSION_CREATE_BY_NID		 108
+#define X509_F_X509_EXTENSION_CREATE_BY_OBJ		 109
+#define X509_F_X509_GET_PUBKEY_PARAMETERS		 110
+#define X509_F_X509_LOAD_CERT_CRL_FILE			 132
+#define X509_F_X509_LOAD_CERT_FILE			 111
+#define X509_F_X509_LOAD_CRL_FILE			 112
+#define X509_F_X509_NAME_ADD_ENTRY			 113
+#define X509_F_X509_NAME_ENTRY_CREATE_BY_NID		 114
+#define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT		 131
+#define X509_F_X509_NAME_ENTRY_SET_OBJECT		 115
+#define X509_F_X509_NAME_ONELINE			 116
+#define X509_F_X509_NAME_PRINT				 117
+#define X509_F_X509_PRINT_EX_FP				 118
+#define X509_F_X509_PUBKEY_GET				 119
+#define X509_F_X509_PUBKEY_SET				 120
+#define X509_F_X509_REQ_CHECK_PRIVATE_KEY		 144
+#define X509_F_X509_REQ_PRINT_EX			 121
+#define X509_F_X509_REQ_PRINT_FP			 122
+#define X509_F_X509_REQ_TO_X509				 123
+#define X509_F_X509_STORE_ADD_CERT			 124
+#define X509_F_X509_STORE_ADD_CRL			 125
+#define X509_F_X509_STORE_CTX_GET1_ISSUER		 146
+#define X509_F_X509_STORE_CTX_INIT			 143
+#define X509_F_X509_STORE_CTX_NEW			 142
+#define X509_F_X509_STORE_CTX_PURPOSE_INHERIT		 134
+#define X509_F_X509_TO_X509_REQ				 126
+#define X509_F_X509_TRUST_ADD				 133
+#define X509_F_X509_TRUST_SET				 141
+#define X509_F_X509_VERIFY_CERT				 127
+
+/* Reason codes. */
+#define X509_R_BAD_X509_FILETYPE			 100
+#define X509_R_BASE64_DECODE_ERROR			 118
+#define X509_R_CANT_CHECK_DH_KEY			 114
+#define X509_R_CERT_ALREADY_IN_HASH_TABLE		 101
+#define X509_R_ERR_ASN1_LIB				 102
+#define X509_R_INVALID_DIRECTORY			 113
+#define X509_R_INVALID_FIELD_NAME			 119
+#define X509_R_INVALID_TRUST				 123
+#define X509_R_KEY_TYPE_MISMATCH			 115
+#define X509_R_KEY_VALUES_MISMATCH			 116
+#define X509_R_LOADING_CERT_DIR				 103
+#define X509_R_LOADING_DEFAULTS				 104
+#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY		 105
+#define X509_R_SHOULD_RETRY				 106
+#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN	 107
+#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY		 108
+#define X509_R_UNKNOWN_KEY_TYPE				 117
+#define X509_R_UNKNOWN_NID				 109
+#define X509_R_UNKNOWN_PURPOSE_ID			 121
+#define X509_R_UNKNOWN_TRUST_ID				 120
+#define X509_R_UNSUPPORTED_ALGORITHM			 111
+#define X509_R_WRONG_LOOKUP_TYPE			 112
+#define X509_R_WRONG_TYPE				 122
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/x509_vfy.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/x509_vfy.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/x509_vfy.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,527 @@
+/* crypto/x509/x509_vfy.h */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#ifndef HEADER_X509_H
+#include <openssl/x509.h>
+/* openssl/x509.h ends up #include-ing this file at about the only
+ * appropriate moment. */
+#endif
+
+#ifndef HEADER_X509_VFY_H
+#define HEADER_X509_VFY_H
+
+#include <openssl/opensslconf.h>
+#ifndef OPENSSL_NO_LHASH
+#include <openssl/lhash.h>
+#endif
+#include <openssl/bio.h>
+#include <openssl/crypto.h>
+#include <openssl/symhacks.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/* Outer object */
+typedef struct x509_hash_dir_st
+	{
+	int num_dirs;
+	char **dirs;
+	int *dirs_type;
+	int num_dirs_alloced;
+	} X509_HASH_DIR_CTX;
+
+typedef struct x509_file_st
+	{
+	int num_paths;	/* number of paths to files or directories */
+	int num_alloced;
+	char **paths;	/* the list of paths or directories */
+	int *path_type;
+	} X509_CERT_FILE_CTX;
+
+/*******************************/
+/*
+SSL_CTX -> X509_STORE    
+		-> X509_LOOKUP
+			->X509_LOOKUP_METHOD
+		-> X509_LOOKUP
+			->X509_LOOKUP_METHOD
+ 
+SSL	-> X509_STORE_CTX
+		->X509_STORE    
+
+The X509_STORE holds the tables etc for verification stuff.
+A X509_STORE_CTX is used while validating a single certificate.
+The X509_STORE has X509_LOOKUPs for looking up certs.
+The X509_STORE then calls a function to actually verify the
+certificate chain.
+*/
+
+#define X509_LU_RETRY		-1
+#define X509_LU_FAIL		0
+#define X509_LU_X509		1
+#define X509_LU_CRL		2
+#define X509_LU_PKEY		3
+
+typedef struct x509_object_st
+	{
+	/* one of the above types */
+	int type;
+	union	{
+		char *ptr;
+		X509 *x509;
+		X509_CRL *crl;
+		EVP_PKEY *pkey;
+		} data;
+	} X509_OBJECT;
+
+typedef struct x509_lookup_st X509_LOOKUP;
+
+DECLARE_STACK_OF(X509_LOOKUP)
+DECLARE_STACK_OF(X509_OBJECT)
+
+/* This is a static that defines the function interface */
+typedef struct x509_lookup_method_st
+	{
+	const char *name;
+	int (*new_item)(X509_LOOKUP *ctx);
+	void (*free)(X509_LOOKUP *ctx);
+	int (*init)(X509_LOOKUP *ctx);
+	int (*shutdown)(X509_LOOKUP *ctx);
+	int (*ctrl)(X509_LOOKUP *ctx,int cmd,const char *argc,long argl,
+			char **ret);
+	int (*get_by_subject)(X509_LOOKUP *ctx,int type,X509_NAME *name,
+			      X509_OBJECT *ret);
+	int (*get_by_issuer_serial)(X509_LOOKUP *ctx,int type,X509_NAME *name,
+				    ASN1_INTEGER *serial,X509_OBJECT *ret);
+	int (*get_by_fingerprint)(X509_LOOKUP *ctx,int type,
+				  unsigned char *bytes,int len,
+				  X509_OBJECT *ret);
+	int (*get_by_alias)(X509_LOOKUP *ctx,int type,char *str,int len,
+			    X509_OBJECT *ret);
+	} X509_LOOKUP_METHOD;
+
+/* This structure hold all parameters associated with a verify operation
+ * by including an X509_VERIFY_PARAM structure in related structures the
+ * parameters used can be customized
+ */
+
+typedef struct X509_VERIFY_PARAM_st
+	{
+	char *name;
+	time_t check_time;	/* Time to use */
+	unsigned long inh_flags; /* Inheritance flags */
+	unsigned long flags;	/* Various verify flags */
+	int purpose;		/* purpose to check untrusted certificates */
+	int trust;		/* trust setting to check */
+	int depth;		/* Verify depth */
+	STACK_OF(ASN1_OBJECT) *policies;	/* Permissible policies */
+	} X509_VERIFY_PARAM;
+
+DECLARE_STACK_OF(X509_VERIFY_PARAM)
+
+/* This is used to hold everything.  It is used for all certificate
+ * validation.  Once we have a certificate chain, the 'verify'
+ * function is then called to actually check the cert chain. */
+struct x509_store_st
+	{
+	/* The following is a cache of trusted certs */
+	int cache; 	/* if true, stash any hits */
+	STACK_OF(X509_OBJECT) *objs;	/* Cache of all objects */
+
+	/* These are external lookup methods */
+	STACK_OF(X509_LOOKUP) *get_cert_methods;
+
+	X509_VERIFY_PARAM *param;
+
+	/* Callbacks for various operations */
+	int (*verify)(X509_STORE_CTX *ctx);	/* called to verify a certificate */
+	int (*verify_cb)(int ok,X509_STORE_CTX *ctx);	/* error callback */
+	int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);	/* get issuers cert from ctx */
+	int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
+	int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
+	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
+	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
+	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
+	int (*cleanup)(X509_STORE_CTX *ctx);
+
+	CRYPTO_EX_DATA ex_data;
+	int references;
+	} /* X509_STORE */;
+
+int X509_STORE_set_depth(X509_STORE *store, int depth);
+
+#define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
+#define X509_STORE_set_verify_func(ctx,func)	((ctx)->verify=(func))
+
+/* This is the functions plus an instance of the local variables. */
+struct x509_lookup_st
+	{
+	int init;			/* have we been started */
+	int skip;			/* don't use us. */
+	X509_LOOKUP_METHOD *method;	/* the functions */
+	char *method_data;		/* method data */
+
+	X509_STORE *store_ctx;	/* who owns us */
+	} /* X509_LOOKUP */;
+
+/* This is a used when verifying cert chains.  Since the
+ * gathering of the cert chain can take some time (and have to be
+ * 'retried', this needs to be kept and passed around. */
+struct x509_store_ctx_st      /* X509_STORE_CTX */
+	{
+	X509_STORE *ctx;
+	int current_method;	/* used when looking up certs */
+
+	/* The following are set by the caller */
+	X509 *cert;		/* The cert to check */
+	STACK_OF(X509) *untrusted;	/* chain of X509s - untrusted - passed in */
+	STACK_OF(X509_CRL) *crls;	/* set of CRLs passed in */
+
+	X509_VERIFY_PARAM *param;
+	void *other_ctx;	/* Other info for use with get_issuer() */
+
+	/* Callbacks for various operations */
+	int (*verify)(X509_STORE_CTX *ctx);	/* called to verify a certificate */
+	int (*verify_cb)(int ok,X509_STORE_CTX *ctx);		/* error callback */
+	int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);	/* get issuers cert from ctx */
+	int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */
+	int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */
+	int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */
+	int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */
+	int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */
+	int (*check_policy)(X509_STORE_CTX *ctx);
+	int (*cleanup)(X509_STORE_CTX *ctx);
+
+	/* The following is built up */
+	int valid;		/* if 0, rebuild chain */
+	int last_untrusted;	/* index of last untrusted cert */
+	STACK_OF(X509) *chain; 		/* chain of X509s - built up and trusted */
+	X509_POLICY_TREE *tree;	/* Valid policy tree */
+
+	int explicit_policy;	/* Require explicit policy value */
+
+	/* When something goes wrong, this is why */
+	int error_depth;
+	int error;
+	X509 *current_cert;
+	X509 *current_issuer;	/* cert currently being tested as valid issuer */
+	X509_CRL *current_crl;	/* current CRL */
+
+	CRYPTO_EX_DATA ex_data;
+	} /* X509_STORE_CTX */;
+
+void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
+
+#define X509_STORE_CTX_set_app_data(ctx,data) \
+	X509_STORE_CTX_set_ex_data(ctx,0,data)
+#define X509_STORE_CTX_get_app_data(ctx) \
+	X509_STORE_CTX_get_ex_data(ctx,0)
+
+#define X509_L_FILE_LOAD	1
+#define X509_L_ADD_DIR		2
+
+#define X509_LOOKUP_load_file(x,name,type) \
+		X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
+
+#define X509_LOOKUP_add_dir(x,name,type) \
+		X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
+
+#define		X509_V_OK					0
+/* illegal error (for uninitialized values, to avoid X509_V_OK): 1 */
+
+#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT		2
+#define		X509_V_ERR_UNABLE_TO_GET_CRL			3
+#define		X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE	4
+#define		X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE	5
+#define		X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY	6
+#define		X509_V_ERR_CERT_SIGNATURE_FAILURE		7
+#define		X509_V_ERR_CRL_SIGNATURE_FAILURE		8
+#define		X509_V_ERR_CERT_NOT_YET_VALID			9
+#define		X509_V_ERR_CERT_HAS_EXPIRED			10
+#define		X509_V_ERR_CRL_NOT_YET_VALID			11
+#define		X509_V_ERR_CRL_HAS_EXPIRED			12
+#define		X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD	13
+#define		X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD	14
+#define		X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD	15
+#define		X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD	16
+#define		X509_V_ERR_OUT_OF_MEM				17
+#define		X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT		18
+#define		X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN		19
+#define		X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY	20
+#define		X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE	21
+#define		X509_V_ERR_CERT_CHAIN_TOO_LONG			22
+#define		X509_V_ERR_CERT_REVOKED				23
+#define		X509_V_ERR_INVALID_CA				24
+#define		X509_V_ERR_PATH_LENGTH_EXCEEDED			25
+#define		X509_V_ERR_INVALID_PURPOSE			26
+#define		X509_V_ERR_CERT_UNTRUSTED			27
+#define		X509_V_ERR_CERT_REJECTED			28
+/* These are 'informational' when looking for issuer cert */
+#define		X509_V_ERR_SUBJECT_ISSUER_MISMATCH		29
+#define		X509_V_ERR_AKID_SKID_MISMATCH			30
+#define		X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH		31
+#define		X509_V_ERR_KEYUSAGE_NO_CERTSIGN			32
+
+#define		X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER		33
+#define		X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION		34
+#define		X509_V_ERR_KEYUSAGE_NO_CRL_SIGN			35
+#define		X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION	36
+#define		X509_V_ERR_INVALID_NON_CA			37
+#define		X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED		38
+#define		X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE	39
+#define		X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED	40
+
+#define		X509_V_ERR_INVALID_EXTENSION			41
+#define		X509_V_ERR_INVALID_POLICY_EXTENSION		42
+#define		X509_V_ERR_NO_EXPLICIT_POLICY			43
+
+
+/* The application is not happy */
+#define		X509_V_ERR_APPLICATION_VERIFICATION		50
+
+/* Certificate verify flags */
+
+/* Send issuer+subject checks to verify_cb */
+#define	X509_V_FLAG_CB_ISSUER_CHECK		0x1
+/* Use check time instead of current time */
+#define	X509_V_FLAG_USE_CHECK_TIME		0x2
+/* Lookup CRLs */
+#define	X509_V_FLAG_CRL_CHECK			0x4
+/* Lookup CRLs for whole chain */
+#define	X509_V_FLAG_CRL_CHECK_ALL		0x8
+/* Ignore unhandled critical extensions */
+#define	X509_V_FLAG_IGNORE_CRITICAL		0x10
+/* Disable workarounds for broken certificates */
+#define	X509_V_FLAG_X509_STRICT			0x20
+/* Enable proxy certificate validation */
+#define	X509_V_FLAG_ALLOW_PROXY_CERTS		0x40
+/* Enable policy checking */
+#define X509_V_FLAG_POLICY_CHECK		0x80
+/* Policy variable require-explicit-policy */
+#define X509_V_FLAG_EXPLICIT_POLICY		0x100
+/* Policy variable inhibit-any-policy */
+#define	X509_V_FLAG_INHIBIT_ANY			0x200
+/* Policy variable inhibit-policy-mapping */
+#define X509_V_FLAG_INHIBIT_MAP			0x400
+/* Notify callback that policy is OK */
+#define X509_V_FLAG_NOTIFY_POLICY		0x800
+
+#define X509_VP_FLAG_DEFAULT			0x1
+#define X509_VP_FLAG_OVERWRITE			0x2
+#define X509_VP_FLAG_RESET_FLAGS		0x4
+#define X509_VP_FLAG_LOCKED			0x8
+#define X509_VP_FLAG_ONCE			0x10
+
+/* Internal use: mask of policy related options */
+#define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
+				| X509_V_FLAG_EXPLICIT_POLICY \
+				| X509_V_FLAG_INHIBIT_ANY \
+				| X509_V_FLAG_INHIBIT_MAP)
+
+int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
+	     X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name);
+X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x);
+void X509_OBJECT_up_ref_count(X509_OBJECT *a);
+void X509_OBJECT_free_contents(X509_OBJECT *a);
+X509_STORE *X509_STORE_new(void );
+void X509_STORE_free(X509_STORE *v);
+
+int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
+int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
+int X509_STORE_set_trust(X509_STORE *ctx, int trust);
+int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
+
+X509_STORE_CTX *X509_STORE_CTX_new(void);
+
+int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
+
+void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
+			 X509 *x509, STACK_OF(X509) *chain);
+void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
+void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
+
+X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
+
+X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
+X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
+
+int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
+int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
+
+int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name,
+	X509_OBJECT *ret);
+
+int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
+	long argl, char **ret);
+
+#ifndef OPENSSL_NO_STDIO
+int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
+#endif
+
+
+X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
+void X509_LOOKUP_free(X509_LOOKUP *ctx);
+int X509_LOOKUP_init(X509_LOOKUP *ctx);
+int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	X509_OBJECT *ret);
+int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
+	ASN1_INTEGER *serial, X509_OBJECT *ret);
+int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
+	unsigned char *bytes, int len, X509_OBJECT *ret);
+int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str,
+	int len, X509_OBJECT *ret);
+int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
+
+#ifndef OPENSSL_NO_STDIO
+int	X509_STORE_load_locations (X509_STORE *ctx,
+		const char *file, const char *dir);
+int	X509_STORE_set_default_paths(X509_STORE *ctx);
+#endif
+
+int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
+	CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
+int	X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data);
+void *	X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx);
+int	X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
+void	X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s);
+int	X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
+X509 *	X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
+STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
+void	X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x);
+void	X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk);
+void	X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk);
+int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
+int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
+int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
+				int purpose, int trust);
+void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
+void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
+								time_t t);
+void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
+				  int (*verify_cb)(int, X509_STORE_CTX *));
+  
+X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
+int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
+
+X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
+void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
+int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
+
+/* X509_VERIFY_PARAM functions */
+
+X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
+void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
+int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
+						const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, 
+						const X509_VERIFY_PARAM *from);
+int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
+int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags);
+int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
+int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
+void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
+void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
+int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
+						ASN1_OBJECT *policy);
+int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
+					STACK_OF(ASN1_OBJECT) *policies);
+int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
+
+int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
+const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
+void X509_VERIFY_PARAM_table_cleanup(void);
+
+int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
+			STACK_OF(X509) *certs,
+			STACK_OF(ASN1_OBJECT) *policy_oids,
+			unsigned int flags);
+
+void X509_policy_tree_free(X509_POLICY_TREE *tree);
+
+int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
+X509_POLICY_LEVEL *
+	X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i);
+
+STACK_OF(X509_POLICY_NODE) *
+	X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree);
+
+STACK_OF(X509_POLICY_NODE) *
+	X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree);
+
+int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
+
+X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i);
+
+const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
+
+STACK_OF(POLICYQUALINFO) *
+	X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node);
+const X509_POLICY_NODE *
+	X509_policy_node_get0_parent(const X509_POLICY_NODE *node);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
+
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/x509v3.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/x509v3.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/openssl/x509v3.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,759 @@
+/* x509v3.h */
+/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+ * project 1999.
+ */
+/* ====================================================================
+ * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    licensing@OpenSSL.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+#ifndef HEADER_X509V3_H
+#define HEADER_X509V3_H
+
+#include <openssl/bio.h>
+#include <openssl/x509.h>
+#include <openssl/conf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Forward reference */
+struct v3_ext_method;
+struct v3_ext_ctx;
+
+/* Useful typedefs */
+
+typedef void * (*X509V3_EXT_NEW)(void);
+typedef void (*X509V3_EXT_FREE)(void *);
+typedef void * (*X509V3_EXT_D2I)(void *, const unsigned char ** , long);
+typedef int (*X509V3_EXT_I2D)(void *, unsigned char **);
+typedef STACK_OF(CONF_VALUE) * (*X509V3_EXT_I2V)(struct v3_ext_method *method, void *ext, STACK_OF(CONF_VALUE) *extlist);
+typedef void * (*X509V3_EXT_V2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, STACK_OF(CONF_VALUE) *values);
+typedef char * (*X509V3_EXT_I2S)(struct v3_ext_method *method, void *ext);
+typedef void * (*X509V3_EXT_S2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str);
+typedef int (*X509V3_EXT_I2R)(struct v3_ext_method *method, void *ext, BIO *out, int indent);
+typedef void * (*X509V3_EXT_R2I)(struct v3_ext_method *method, struct v3_ext_ctx *ctx, const char *str);
+
+/* V3 extension structure */
+
+struct v3_ext_method {
+int ext_nid;
+int ext_flags;
+/* If this is set the following four fields are ignored */
+ASN1_ITEM_EXP *it;
+/* Old style ASN1 calls */
+X509V3_EXT_NEW ext_new;
+X509V3_EXT_FREE ext_free;
+X509V3_EXT_D2I d2i;
+X509V3_EXT_I2D i2d;
+
+/* The following pair is used for string extensions */
+X509V3_EXT_I2S i2s;
+X509V3_EXT_S2I s2i;
+
+/* The following pair is used for multi-valued extensions */
+X509V3_EXT_I2V i2v;
+X509V3_EXT_V2I v2i;
+
+/* The following are used for raw extensions */
+X509V3_EXT_I2R i2r;
+X509V3_EXT_R2I r2i;
+
+void *usr_data;	/* Any extension specific data */
+};
+
+typedef struct X509V3_CONF_METHOD_st {
+char * (*get_string)(void *db, char *section, char *value);
+STACK_OF(CONF_VALUE) * (*get_section)(void *db, char *section);
+void (*free_string)(void *db, char * string);
+void (*free_section)(void *db, STACK_OF(CONF_VALUE) *section);
+} X509V3_CONF_METHOD;
+
+/* Context specific info */
+struct v3_ext_ctx {
+#define CTX_TEST 0x1
+int flags;
+X509 *issuer_cert;
+X509 *subject_cert;
+X509_REQ *subject_req;
+X509_CRL *crl;
+X509V3_CONF_METHOD *db_meth;
+void *db;
+/* Maybe more here */
+};
+
+typedef struct v3_ext_method X509V3_EXT_METHOD;
+
+DECLARE_STACK_OF(X509V3_EXT_METHOD)
+
+/* ext_flags values */
+#define X509V3_EXT_DYNAMIC	0x1
+#define X509V3_EXT_CTX_DEP	0x2
+#define X509V3_EXT_MULTILINE	0x4
+
+typedef BIT_STRING_BITNAME ENUMERATED_NAMES;
+
+typedef struct BASIC_CONSTRAINTS_st {
+int ca;
+ASN1_INTEGER *pathlen;
+} BASIC_CONSTRAINTS;
+
+
+typedef struct PKEY_USAGE_PERIOD_st {
+ASN1_GENERALIZEDTIME *notBefore;
+ASN1_GENERALIZEDTIME *notAfter;
+} PKEY_USAGE_PERIOD;
+
+typedef struct otherName_st {
+ASN1_OBJECT *type_id;
+ASN1_TYPE *value;
+} OTHERNAME;
+
+typedef struct EDIPartyName_st {
+	ASN1_STRING *nameAssigner;
+	ASN1_STRING *partyName;
+} EDIPARTYNAME;
+
+typedef struct GENERAL_NAME_st {
+
+#define GEN_OTHERNAME	0
+#define GEN_EMAIL	1
+#define GEN_DNS		2
+#define GEN_X400	3
+#define GEN_DIRNAME	4
+#define GEN_EDIPARTY	5
+#define GEN_URI		6
+#define GEN_IPADD	7
+#define GEN_RID		8
+
+int type;
+union {
+	char *ptr;
+	OTHERNAME *otherName; /* otherName */
+	ASN1_IA5STRING *rfc822Name;
+	ASN1_IA5STRING *dNSName;
+	ASN1_TYPE *x400Address;
+	X509_NAME *directoryName;
+	EDIPARTYNAME *ediPartyName;
+	ASN1_IA5STRING *uniformResourceIdentifier;
+	ASN1_OCTET_STRING *iPAddress;
+	ASN1_OBJECT *registeredID;
+
+	/* Old names */
+	ASN1_OCTET_STRING *ip; /* iPAddress */
+	X509_NAME *dirn;		/* dirn */
+	ASN1_IA5STRING *ia5;/* rfc822Name, dNSName, uniformResourceIdentifier */
+	ASN1_OBJECT *rid; /* registeredID */
+	ASN1_TYPE *other; /* x400Address */
+} d;
+} GENERAL_NAME;
+
+typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES;
+
+typedef struct ACCESS_DESCRIPTION_st {
+	ASN1_OBJECT *method;
+	GENERAL_NAME *location;
+} ACCESS_DESCRIPTION;
+
+typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
+
+typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE;
+
+DECLARE_STACK_OF(GENERAL_NAME)
+DECLARE_ASN1_SET_OF(GENERAL_NAME)
+
+DECLARE_STACK_OF(ACCESS_DESCRIPTION)
+DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION)
+
+typedef struct DIST_POINT_NAME_st {
+int type;
+union {
+	GENERAL_NAMES *fullname;
+	STACK_OF(X509_NAME_ENTRY) *relativename;
+} name;
+} DIST_POINT_NAME;
+
+typedef struct DIST_POINT_st {
+DIST_POINT_NAME	*distpoint;
+ASN1_BIT_STRING *reasons;
+GENERAL_NAMES *CRLissuer;
+} DIST_POINT;
+
+typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS;
+
+DECLARE_STACK_OF(DIST_POINT)
+DECLARE_ASN1_SET_OF(DIST_POINT)
+
+typedef struct AUTHORITY_KEYID_st {
+ASN1_OCTET_STRING *keyid;
+GENERAL_NAMES *issuer;
+ASN1_INTEGER *serial;
+} AUTHORITY_KEYID;
+
+/* Strong extranet structures */
+
+typedef struct SXNET_ID_st {
+	ASN1_INTEGER *zone;
+	ASN1_OCTET_STRING *user;
+} SXNETID;
+
+DECLARE_STACK_OF(SXNETID)
+DECLARE_ASN1_SET_OF(SXNETID)
+
+typedef struct SXNET_st {
+	ASN1_INTEGER *version;
+	STACK_OF(SXNETID) *ids;
+} SXNET;
+
+typedef struct NOTICEREF_st {
+	ASN1_STRING *organization;
+	STACK_OF(ASN1_INTEGER) *noticenos;
+} NOTICEREF;
+
+typedef struct USERNOTICE_st {
+	NOTICEREF *noticeref;
+	ASN1_STRING *exptext;
+} USERNOTICE;
+
+typedef struct POLICYQUALINFO_st {
+	ASN1_OBJECT *pqualid;
+	union {
+		ASN1_IA5STRING *cpsuri;
+		USERNOTICE *usernotice;
+		ASN1_TYPE *other;
+	} d;
+} POLICYQUALINFO;
+
+DECLARE_STACK_OF(POLICYQUALINFO)
+DECLARE_ASN1_SET_OF(POLICYQUALINFO)
+
+typedef struct POLICYINFO_st {
+	ASN1_OBJECT *policyid;
+	STACK_OF(POLICYQUALINFO) *qualifiers;
+} POLICYINFO;
+
+typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES;
+
+DECLARE_STACK_OF(POLICYINFO)
+DECLARE_ASN1_SET_OF(POLICYINFO)
+
+typedef struct POLICY_MAPPING_st {
+	ASN1_OBJECT *issuerDomainPolicy;
+	ASN1_OBJECT *subjectDomainPolicy;
+} POLICY_MAPPING;
+
+DECLARE_STACK_OF(POLICY_MAPPING)
+
+typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS;
+
+typedef struct GENERAL_SUBTREE_st {
+	GENERAL_NAME *base;
+	ASN1_INTEGER *minimum;
+	ASN1_INTEGER *maximum;
+} GENERAL_SUBTREE;
+
+DECLARE_STACK_OF(GENERAL_SUBTREE)
+
+typedef struct NAME_CONSTRAINTS_st {
+	STACK_OF(GENERAL_SUBTREE) *permittedSubtrees;
+	STACK_OF(GENERAL_SUBTREE) *excludedSubtrees;
+} NAME_CONSTRAINTS;
+
+typedef struct POLICY_CONSTRAINTS_st {
+	ASN1_INTEGER *requireExplicitPolicy;
+	ASN1_INTEGER *inhibitPolicyMapping;
+} POLICY_CONSTRAINTS;
+
+/* Proxy certificate structures, see RFC 3820 */
+typedef struct PROXY_POLICY_st
+	{
+	ASN1_OBJECT *policyLanguage;
+	ASN1_OCTET_STRING *policy;
+	} PROXY_POLICY;
+
+typedef struct PROXY_CERT_INFO_EXTENSION_st
+	{
+	ASN1_INTEGER *pcPathLengthConstraint;
+	PROXY_POLICY *proxyPolicy;
+	} PROXY_CERT_INFO_EXTENSION;
+
+DECLARE_ASN1_FUNCTIONS(PROXY_POLICY)
+DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION)
+
+
+#define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
+",name:", val->name, ",value:", val->value);
+
+#define X509V3_set_ctx_test(ctx) \
+			X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
+#define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL;
+
+#define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \
+			0,0,0,0, \
+			0,0, \
+			(X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \
+			(X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \
+			NULL, NULL, \
+			table}
+
+#define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \
+			0,0,0,0, \
+			(X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \
+			(X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \
+			0,0,0,0, \
+			NULL}
+
+#define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+
+
+/* X509_PURPOSE stuff */
+
+#define EXFLAG_BCONS		0x1
+#define EXFLAG_KUSAGE		0x2
+#define EXFLAG_XKUSAGE		0x4
+#define EXFLAG_NSCERT		0x8
+
+#define EXFLAG_CA		0x10
+#define EXFLAG_SS		0x20
+#define EXFLAG_V1		0x40
+#define EXFLAG_INVALID		0x80
+#define EXFLAG_SET		0x100
+#define EXFLAG_CRITICAL		0x200
+#define EXFLAG_PROXY		0x400
+
+#define EXFLAG_INVALID_POLICY	0x400
+
+#define KU_DIGITAL_SIGNATURE	0x0080
+#define KU_NON_REPUDIATION	0x0040
+#define KU_KEY_ENCIPHERMENT	0x0020
+#define KU_DATA_ENCIPHERMENT	0x0010
+#define KU_KEY_AGREEMENT	0x0008
+#define KU_KEY_CERT_SIGN	0x0004
+#define KU_CRL_SIGN		0x0002
+#define KU_ENCIPHER_ONLY	0x0001
+#define KU_DECIPHER_ONLY	0x8000
+
+#define NS_SSL_CLIENT		0x80
+#define NS_SSL_SERVER		0x40
+#define NS_SMIME		0x20
+#define NS_OBJSIGN		0x10
+#define NS_SSL_CA		0x04
+#define NS_SMIME_CA		0x02
+#define NS_OBJSIGN_CA		0x01
+#define NS_ANY_CA		(NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA)
+
+#define XKU_SSL_SERVER		0x1	
+#define XKU_SSL_CLIENT		0x2
+#define XKU_SMIME		0x4
+#define XKU_CODE_SIGN		0x8
+#define XKU_SGC			0x10
+#define XKU_OCSP_SIGN		0x20
+#define XKU_TIMESTAMP		0x40
+#define XKU_DVCS		0x80
+
+#define X509_PURPOSE_DYNAMIC	0x1
+#define X509_PURPOSE_DYNAMIC_NAME	0x2
+
+typedef struct x509_purpose_st {
+	int purpose;
+	int trust;		/* Default trust ID */
+	int flags;
+	int (*check_purpose)(const struct x509_purpose_st *,
+				const X509 *, int);
+	char *name;
+	char *sname;
+	void *usr_data;
+} X509_PURPOSE;
+
+#define X509_PURPOSE_SSL_CLIENT		1
+#define X509_PURPOSE_SSL_SERVER		2
+#define X509_PURPOSE_NS_SSL_SERVER	3
+#define X509_PURPOSE_SMIME_SIGN		4
+#define X509_PURPOSE_SMIME_ENCRYPT	5
+#define X509_PURPOSE_CRL_SIGN		6
+#define X509_PURPOSE_ANY		7
+#define X509_PURPOSE_OCSP_HELPER	8
+
+#define X509_PURPOSE_MIN		1
+#define X509_PURPOSE_MAX		8
+
+/* Flags for X509V3_EXT_print() */
+
+#define X509V3_EXT_UNKNOWN_MASK		(0xfL << 16)
+/* Return error for unknown extensions */
+#define X509V3_EXT_DEFAULT		0
+/* Print error for unknown extensions */
+#define X509V3_EXT_ERROR_UNKNOWN	(1L << 16)
+/* ASN1 parse unknown extensions */
+#define X509V3_EXT_PARSE_UNKNOWN	(2L << 16)
+/* BIO_dump unknown extensions */
+#define X509V3_EXT_DUMP_UNKNOWN		(3L << 16)
+
+/* Flags for X509V3_add1_i2d */
+
+#define X509V3_ADD_OP_MASK		0xfL
+#define X509V3_ADD_DEFAULT		0L
+#define X509V3_ADD_APPEND		1L
+#define X509V3_ADD_REPLACE		2L
+#define X509V3_ADD_REPLACE_EXISTING	3L
+#define X509V3_ADD_KEEP_EXISTING	4L
+#define X509V3_ADD_DELETE		5L
+#define X509V3_ADD_SILENT		0x10
+
+DECLARE_STACK_OF(X509_PURPOSE)
+
+DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS)
+
+DECLARE_ASN1_FUNCTIONS(SXNET)
+DECLARE_ASN1_FUNCTIONS(SXNETID)
+
+int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen); 
+int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, int userlen); 
+int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user, int userlen); 
+
+ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone);
+ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone);
+ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone);
+
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID)
+
+DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD)
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAME)
+
+
+ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
+				ASN1_BIT_STRING *bits,
+				STACK_OF(CONF_VALUE) *extlist);
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret);
+int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen);
+
+DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES)
+
+STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+		GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist);
+GENERAL_NAMES *v2i_GENERAL_NAMES(X509V3_EXT_METHOD *method,
+				X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval);
+
+DECLARE_ASN1_FUNCTIONS(OTHERNAME)
+DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
+
+char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5);
+ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str);
+
+DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE)
+int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION* a);
+
+DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES)
+DECLARE_ASN1_FUNCTIONS(POLICYINFO)
+DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO)
+DECLARE_ASN1_FUNCTIONS(USERNOTICE)
+DECLARE_ASN1_FUNCTIONS(NOTICEREF)
+
+DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT)
+DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME)
+
+DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
+DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
+
+DECLARE_ASN1_ITEM(POLICY_MAPPING)
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING)
+DECLARE_ASN1_ITEM(POLICY_MAPPINGS)
+
+DECLARE_ASN1_ITEM(GENERAL_SUBTREE)
+DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE)
+
+DECLARE_ASN1_ITEM(NAME_CONSTRAINTS)
+DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS)
+
+DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS)
+DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS)
+
+#ifdef HEADER_CONF_H
+GENERAL_NAME *v2i_GENERAL_NAME(X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
+							CONF_VALUE *cnf);
+GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, X509V3_EXT_METHOD *method,
+				X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc);
+void X509V3_conf_free(CONF_VALUE *val);
+
+X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value);
+X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value);
+int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk);
+int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert);
+int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
+
+X509_EXTENSION *X509V3_EXT_conf_nid(LHASH *conf, X509V3_CTX *ctx, int ext_nid, char *value);
+X509_EXTENSION *X509V3_EXT_conf(LHASH *conf, X509V3_CTX *ctx, char *name, char *value);
+int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509 *cert);
+int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_REQ *req);
+int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl);
+
+int X509V3_add_value_bool_nf(char *name, int asn1_bool,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool);
+int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint);
+void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf);
+void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH *lhash);
+#endif
+
+char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section);
+STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section);
+void X509V3_string_free(X509V3_CTX *ctx, char *str);
+void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section);
+void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject,
+				 X509_REQ *req, X509_CRL *crl, int flags);
+
+int X509V3_add_value(const char *name, const char *value,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_uchar(const char *name, const unsigned char *value,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_bool(const char *name, int asn1_bool,
+						STACK_OF(CONF_VALUE) **extlist);
+int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint,
+						STACK_OF(CONF_VALUE) **extlist);
+char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint);
+ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value);
+char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint);
+int X509V3_EXT_add(X509V3_EXT_METHOD *ext);
+int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist);
+int X509V3_EXT_add_alias(int nid_to, int nid_from);
+void X509V3_EXT_cleanup(void);
+
+X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext);
+X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid);
+int X509V3_add_standard_extensions(void);
+STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line);
+void *X509V3_EXT_d2i(X509_EXTENSION *ext);
+void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx);
+
+
+X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc);
+int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags);
+
+char *hex_to_string(unsigned char *buffer, long len);
+unsigned char *string_to_hex(char *str, long *len);
+int name_cmp(const char *name, const char *cmp);
+
+void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent,
+								 int ml);
+int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent);
+int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent);
+
+int X509V3_extensions_print(BIO *out, char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent);
+
+int X509_check_ca(X509 *x);
+int X509_check_purpose(X509 *x, int id, int ca);
+int X509_supported_extension(X509_EXTENSION *ex);
+int X509_PURPOSE_set(int *p, int purpose);
+int X509_check_issued(X509 *issuer, X509 *subject);
+int X509_PURPOSE_get_count(void);
+X509_PURPOSE * X509_PURPOSE_get0(int idx);
+int X509_PURPOSE_get_by_sname(char *sname);
+int X509_PURPOSE_get_by_id(int id);
+int X509_PURPOSE_add(int id, int trust, int flags,
+			int (*ck)(const X509_PURPOSE *, const X509 *, int),
+				char *name, char *sname, void *arg);
+char *X509_PURPOSE_get0_name(X509_PURPOSE *xp);
+char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp);
+int X509_PURPOSE_get_trust(X509_PURPOSE *xp);
+void X509_PURPOSE_cleanup(void);
+int X509_PURPOSE_get_id(X509_PURPOSE *);
+
+STACK *X509_get1_email(X509 *x);
+STACK *X509_REQ_get1_email(X509_REQ *x);
+void X509_email_free(STACK *sk);
+
+ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc);
+ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc);
+int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk,
+						unsigned long chtype);
+
+void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent);
+
+/* BEGIN ERROR CODES */
+/* The following lines are auto generated by the script mkerr.pl. Any changes
+ * made after this point may be overwritten when the script is next run.
+ */
+void ERR_load_X509V3_strings(void);
+
+/* Error codes for the X509V3 functions. */
+
+/* Function codes. */
+#define X509V3_F_COPY_EMAIL				 122
+#define X509V3_F_COPY_ISSUER				 123
+#define X509V3_F_DO_DIRNAME				 144
+#define X509V3_F_DO_EXT_CONF				 124
+#define X509V3_F_DO_EXT_I2D				 135
+#define X509V3_F_DO_EXT_NCONF				 151
+#define X509V3_F_DO_I2V_NAME_CONSTRAINTS		 148
+#define X509V3_F_HEX_TO_STRING				 111
+#define X509V3_F_I2S_ASN1_ENUMERATED			 121
+#define X509V3_F_I2S_ASN1_IA5STRING			 149
+#define X509V3_F_I2S_ASN1_INTEGER			 120
+#define X509V3_F_I2V_AUTHORITY_INFO_ACCESS		 138
+#define X509V3_F_NOTICE_SECTION				 132
+#define X509V3_F_NREF_NOS				 133
+#define X509V3_F_POLICY_SECTION				 131
+#define X509V3_F_PROCESS_PCI_VALUE			 150
+#define X509V3_F_R2I_CERTPOL				 130
+#define X509V3_F_R2I_PCI				 149
+#define X509V3_F_S2I_ASN1_IA5STRING			 100
+#define X509V3_F_S2I_ASN1_INTEGER			 108
+#define X509V3_F_S2I_ASN1_OCTET_STRING			 112
+#define X509V3_F_S2I_ASN1_SKEY_ID			 114
+#define X509V3_F_S2I_SKEY_ID				 115
+#define X509V3_F_STRING_TO_HEX				 113
+#define X509V3_F_SXNET_ADD_ID_ASC			 125
+#define X509V3_F_SXNET_ADD_ID_INTEGER			 126
+#define X509V3_F_SXNET_ADD_ID_ULONG			 127
+#define X509V3_F_SXNET_GET_ID_ASC			 128
+#define X509V3_F_SXNET_GET_ID_ULONG			 129
+#define X509V3_F_V2I_ASN1_BIT_STRING			 101
+#define X509V3_F_V2I_AUTHORITY_INFO_ACCESS		 139
+#define X509V3_F_V2I_AUTHORITY_KEYID			 119
+#define X509V3_F_V2I_BASIC_CONSTRAINTS			 102
+#define X509V3_F_V2I_CRLD				 134
+#define X509V3_F_V2I_EXTENDED_KEY_USAGE			 103
+#define X509V3_F_V2I_GENERAL_NAMES			 118
+#define X509V3_F_V2I_GENERAL_NAME_EX			 117
+#define X509V3_F_V2I_ISSUER_ALT				 153
+#define X509V3_F_V2I_NAME_CONSTRAINTS			 147
+#define X509V3_F_V2I_POLICY_CONSTRAINTS			 146
+#define X509V3_F_V2I_POLICY_MAPPINGS			 145
+#define X509V3_F_V2I_SUBJECT_ALT			 154
+#define X509V3_F_V3_GENERIC_EXTENSION			 116
+#define X509V3_F_X509V3_ADD1_I2D			 140
+#define X509V3_F_X509V3_ADD_VALUE			 105
+#define X509V3_F_X509V3_EXT_ADD				 104
+#define X509V3_F_X509V3_EXT_ADD_ALIAS			 106
+#define X509V3_F_X509V3_EXT_CONF			 107
+#define X509V3_F_X509V3_EXT_I2D				 136
+#define X509V3_F_X509V3_EXT_NCONF			 152
+#define X509V3_F_X509V3_GET_SECTION			 142
+#define X509V3_F_X509V3_GET_STRING			 143
+#define X509V3_F_X509V3_GET_VALUE_BOOL			 110
+#define X509V3_F_X509V3_PARSE_LIST			 109
+#define X509V3_F_X509_PURPOSE_ADD			 137
+#define X509V3_F_X509_PURPOSE_SET			 141
+
+/* Reason codes. */
+#define X509V3_R_BAD_IP_ADDRESS				 118
+#define X509V3_R_BAD_OBJECT				 119
+#define X509V3_R_BN_DEC2BN_ERROR			 100
+#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR		 101
+#define X509V3_R_DIRNAME_ERROR				 149
+#define X509V3_R_DUPLICATE_ZONE_ID			 133
+#define X509V3_R_ERROR_CONVERTING_ZONE			 131
+#define X509V3_R_ERROR_CREATING_EXTENSION		 144
+#define X509V3_R_ERROR_IN_EXTENSION			 128
+#define X509V3_R_EXPECTED_A_SECTION_NAME		 137
+#define X509V3_R_EXTENSION_EXISTS			 145
+#define X509V3_R_EXTENSION_NAME_ERROR			 115
+#define X509V3_R_EXTENSION_NOT_FOUND			 102
+#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED	 103
+#define X509V3_R_EXTENSION_VALUE_ERROR			 116
+#define X509V3_R_ILLEGAL_EMPTY_EXTENSION		 151
+#define X509V3_R_ILLEGAL_HEX_DIGIT			 113
+#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG		 152
+#define X509V3_R_INVALID_BOOLEAN_STRING			 104
+#define X509V3_R_INVALID_EXTENSION_STRING		 105
+#define X509V3_R_INVALID_NAME				 106
+#define X509V3_R_INVALID_NULL_ARGUMENT			 107
+#define X509V3_R_INVALID_NULL_NAME			 108
+#define X509V3_R_INVALID_NULL_VALUE			 109
+#define X509V3_R_INVALID_NUMBER				 140
+#define X509V3_R_INVALID_NUMBERS			 141
+#define X509V3_R_INVALID_OBJECT_IDENTIFIER		 110
+#define X509V3_R_INVALID_OPTION				 138
+#define X509V3_R_INVALID_POLICY_IDENTIFIER		 134
+#define X509V3_R_INVALID_PROXY_POLICY_SETTING		 153
+#define X509V3_R_INVALID_PURPOSE			 146
+#define X509V3_R_INVALID_SECTION			 135
+#define X509V3_R_INVALID_SYNTAX				 143
+#define X509V3_R_ISSUER_DECODE_ERROR			 126
+#define X509V3_R_MISSING_VALUE				 124
+#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS		 142
+#define X509V3_R_NO_CONFIG_DATABASE			 136
+#define X509V3_R_NO_ISSUER_CERTIFICATE			 121
+#define X509V3_R_NO_ISSUER_DETAILS			 127
+#define X509V3_R_NO_POLICY_IDENTIFIER			 139
+#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED	 154
+#define X509V3_R_NO_PUBLIC_KEY				 114
+#define X509V3_R_NO_SUBJECT_DETAILS			 125
+#define X509V3_R_ODD_NUMBER_OF_DIGITS			 112
+#define X509V3_R_OPERATION_NOT_DEFINED			 148
+#define X509V3_R_OTHERNAME_ERROR			 147
+#define X509V3_R_POLICY_LANGUAGE_ALREADTY_DEFINED	 155
+#define X509V3_R_POLICY_PATH_LENGTH			 156
+#define X509V3_R_POLICY_PATH_LENGTH_ALREADTY_DEFINED	 157
+#define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED	 158
+#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159
+#define X509V3_R_SECTION_NOT_FOUND			 150
+#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS		 122
+#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID		 123
+#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT		 111
+#define X509V3_R_UNKNOWN_EXTENSION			 129
+#define X509V3_R_UNKNOWN_EXTENSION_NAME			 130
+#define X509V3_R_UNKNOWN_OPTION				 120
+#define X509V3_R_UNSUPPORTED_OPTION			 117
+#define X509V3_R_USER_TOO_LONG				 132
+
+#ifdef  __cplusplus
+}
+#endif
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/pkcs11.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/pkcs11.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/pkcs11.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,299 @@
+/* pkcs11.h include file for PKCS #11. */
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the 
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+#ifndef _PKCS11_H_
+#define _PKCS11_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Before including this file (pkcs11.h) (or pkcs11t.h by
+ * itself), 6 platform-specific macros must be defined.  These
+ * macros are described below, and typical definitions for them
+ * are also given.  Be advised that these definitions can depend
+ * on both the platform and the compiler used (and possibly also
+ * on whether a Cryptoki library is linked statically or
+ * dynamically).
+ *
+ * In addition to defining these 6 macros, the packing convention
+ * for Cryptoki structures should be set.  The Cryptoki
+ * convention on packing is that structures should be 1-byte
+ * aligned.
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, this might be done by using the following
+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(push, cryptoki, 1)
+ *
+ * and using the following preprocessor directive after including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(pop, cryptoki)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, this might be done by using
+ * the following preprocessor directive before including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(1)
+ *
+ * In a UNIX environment, you're on your own for this.  You might
+ * not need to do (or be able to do!) anything.
+ *
+ *
+ * Now for the macros:
+ *
+ *
+ * 1. CK_PTR: The indirection string for making a pointer to an
+ * object.  It can be used like this:
+ *
+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, it might be defined by:
+ *
+ * #define CK_PTR far *
+ *
+ * In a typical UNIX environment, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ *
+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
+ * an exportable Cryptoki library function definition out of a
+ * return type and a function name.  It should be used in the
+ * following fashion to define the exposed Cryptoki functions in
+ * a Cryptoki library:
+ *
+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
+ *   CK_VOID_PTR pReserved
+ * )
+ * {
+ *   ...
+ * }
+ *
+ * If you're using Microsoft Developer Studio 5.0 to define a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ *   returnType __declspec(dllexport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to define a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ *   returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ *   returnType name
+ *
+ *
+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
+ * an importable Cryptoki library function declaration out of a
+ * return type and a function name.  It should be used in the
+ * following fashion:
+ *
+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
+ *   CK_VOID_PTR pReserved
+ * );
+ *
+ * If you're using Microsoft Developer Studio 5.0 to declare a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ *   returnType __declspec(dllimport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to declare a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ *   returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ *   returnType name
+ *
+ *
+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
+ * which makes a Cryptoki API function pointer declaration or
+ * function pointer type declaration out of a return type and a
+ * function name.  It should be used in the following fashion:
+ *
+ * // Define funcPtr to be a pointer to a Cryptoki API function
+ * // taking arguments args and returning CK_RV.
+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
+ *
+ * or
+ *
+ * // Define funcPtrType to be the type of a pointer to a
+ * // Cryptoki API function taking arguments args and returning
+ * // CK_RV, and then define funcPtr to be a variable of type
+ * // funcPtrType.
+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
+ * funcPtrType funcPtr;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to access
+ * functions in a Win32 Cryptoki .dll, in might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ *   returnType __declspec(dllimport) (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to access functions in a Win16 Cryptoki .dll, it might
+ * be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ *   returnType __export _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ *   returnType (* name)
+ *
+ *
+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
+ * a function pointer type for an application callback out of
+ * a return type for the callback and a name for the callback.
+ * It should be used in the following fashion:
+ *
+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
+ *
+ * to declare a function pointer, myCallback, to a callback
+ * which takes arguments args and returns a CK_RV.  It can also
+ * be used like this:
+ *
+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
+ * myCallbackType myCallback;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to do Win32
+ * Cryptoki development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ *   returnType (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to do Win16 development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ *   returnType _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ *   returnType (* name)
+ *
+ *
+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
+ *
+ * In any ANSI/ISO C environment (and in many others as well),
+ * this should best be defined by
+ *
+ * #ifndef NULL_PTR
+ * #define NULL_PTR 0
+ * #endif
+ */
+
+
+/* All the various Cryptoki types and #define'd values are in the
+ * file pkcs11t.h. */
+#include "pkcs11t.h"
+
+#define __PASTE(x,y)      x##y
+
+
+/* ==============================================================
+ * Define the "extern" form of all the entry points.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST  1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+  extern CK_DECLARE_FUNCTION(CK_RV, name)
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define the typedef form of all the entry points.  That is, for
+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
+ * a pointer to that kind of function.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST  1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define structed vector of entry points.  A CK_FUNCTION_LIST
+ * contains a CK_VERSION indicating a library's Cryptoki version
+ * and then a whole slew of function pointers to the routines in
+ * the library.  This type was declared, but not defined, in
+ * pkcs11t.h.
+ * ==============================================================
+ */
+
+#define CK_PKCS11_FUNCTION_INFO(name) \
+  __PASTE(CK_,name) name;
+  
+struct CK_FUNCTION_LIST {
+
+  CK_VERSION    version;  /* Cryptoki version */
+
+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+};
+
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+#undef __PASTE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/pkcs11f.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/pkcs11f.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/pkcs11f.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,912 @@
+/* pkcs11f.h include file for PKCS #11. */
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the 
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* This header file contains pretty much everything about all the */
+/* Cryptoki function prototypes.  Because this information is */
+/* used for more than just declaring function prototypes, the */
+/* order of the functions appearing herein is important, and */
+/* should not be altered. */
+
+/* General-purpose */
+
+/* C_Initialize initializes the Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Initialize)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
+                            * cast to CK_C_INITIALIZE_ARGS_PTR
+                            * and dereferenced */
+);
+#endif
+
+
+/* C_Finalize indicates that an application is done with the
+ * Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Finalize)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
+);
+#endif
+
+
+/* C_GetInfo returns general information about Cryptoki. */
+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_INFO_PTR   pInfo  /* location that receives information */
+);
+#endif
+
+
+/* C_GetFunctionList returns the function list. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
+                                            * function list */
+);
+#endif
+
+
+
+/* Slot and token management */
+
+/* C_GetSlotList obtains a list of slots in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
+  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
+  CK_ULONG_PTR   pulCount       /* receives number of slots */
+);
+#endif
+
+
+/* C_GetSlotInfo obtains information about a particular slot in
+ * the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID       slotID,  /* the ID of the slot */
+  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
+);
+#endif
+
+
+/* C_GetTokenInfo obtains information about a particular token
+ * in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID        slotID,  /* ID of the token's slot */
+  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
+);
+#endif
+
+
+/* C_GetMechanismList obtains a list of mechanism types
+ * supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID            slotID,          /* ID of token's slot */
+  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
+  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
+);
+#endif
+
+
+/* C_GetMechanismInfo obtains information about a particular
+ * mechanism possibly supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID            slotID,  /* ID of the token's slot */
+  CK_MECHANISM_TYPE     type,    /* type of mechanism */
+  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
+);
+#endif
+
+
+/* C_InitToken initializes a token. */
+CK_PKCS11_FUNCTION_INFO(C_InitToken)
+#ifdef CK_NEED_ARG_LIST
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
+(
+  CK_SLOT_ID      slotID,    /* ID of the token's slot */
+  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
+  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
+  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
+);
+#endif
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
+  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
+);
+#endif
+
+
+/* C_SetPIN modifies the PIN of the user who is logged in. */
+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
+  CK_ULONG          ulOldLen,  /* length of the old PIN */
+  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
+  CK_ULONG          ulNewLen   /* length of the new PIN */
+);
+#endif
+
+
+
+/* Session management */
+
+/* C_OpenSession opens a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID            slotID,        /* the slot's ID */
+  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
+  CK_VOID_PTR           pApplication,  /* passed to callback */
+  CK_NOTIFY             Notify,        /* callback function */
+  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
+);
+#endif
+
+
+/* C_CloseSession closes a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SLOT_ID     slotID  /* the token's slot */
+);
+#endif
+
+
+/* C_GetSessionInfo obtains information about the session. */
+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE   hSession,  /* the session's handle */
+  CK_SESSION_INFO_PTR pInfo      /* receives session info */
+);
+#endif
+
+
+/* C_GetOperationState obtains the state of the cryptographic operation
+ * in a session. */
+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,             /* session's handle */
+  CK_BYTE_PTR       pOperationState,      /* gets state */
+  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
+);
+#endif
+
+
+/* C_SetOperationState restores the state of the cryptographic
+ * operation in a session. */
+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR      pOperationState,      /* holds state */
+  CK_ULONG         ulOperationStateLen,  /* holds state length */
+  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
+  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
+);
+#endif
+
+
+/* C_Login logs a user into a token. */
+CK_PKCS11_FUNCTION_INFO(C_Login)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_USER_TYPE      userType,  /* the user type */
+  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
+  CK_ULONG          ulPinLen   /* the length of the PIN */
+);
+#endif
+
+
+/* C_Logout logs a user out from a token. */
+CK_PKCS11_FUNCTION_INFO(C_Logout)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+
+/* Object management */
+
+/* C_CreateObject creates a new object. */
+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
+  CK_ULONG          ulCount,     /* attributes in template */
+  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
+);
+#endif
+
+
+/* C_CopyObject copies an object, creating a new object for the
+ * copy. */
+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
+  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
+  CK_ULONG             ulCount,     /* attributes in template */
+  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
+);
+#endif
+
+
+/* C_DestroyObject destroys an object. */
+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_OBJECT_HANDLE  hObject    /* the object's handle */
+);
+#endif
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
+  CK_ULONG_PTR      pulSize    /* receives size of object */
+);
+#endif
+
+
+/* C_GetAttributeValue obtains the value of one or more object
+ * attributes. */
+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
+  CK_ULONG          ulCount     /* attributes in template */
+);
+#endif
+
+
+/* C_SetAttributeValue modifies the value of one or more object
+ * attributes */
+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
+  CK_ULONG          ulCount     /* attributes in template */
+);
+#endif
+
+
+/* C_FindObjectsInit initializes a search for token and session
+ * objects that match a template. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
+  CK_ULONG          ulCount     /* attrs in search template */
+);
+#endif
+
+
+/* C_FindObjects continues a search for token and session
+ * objects that match a template, obtaining additional object
+ * handles. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE    hSession,          /* session's handle */
+ CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
+ CK_ULONG             ulMaxObjectCount,  /* max handles to get */
+ CK_ULONG_PTR         pulObjectCount     /* actual # returned */
+);
+#endif
+
+
+/* C_FindObjectsFinal finishes a search for token and session
+ * objects. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+
+/* Encryption and decryption */
+
+/* C_EncryptInit initializes an encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
+  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
+);
+#endif
+
+
+/* C_Encrypt encrypts single-part data. */
+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pData,               /* the plaintext data */
+  CK_ULONG          ulDataLen,           /* bytes of plaintext */
+  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
+  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptUpdate continues a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,           /* session's handle */
+  CK_BYTE_PTR       pPart,              /* the plaintext data */
+  CK_ULONG          ulPartLen,          /* plaintext data len */
+  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
+  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptFinal finishes a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,                /* session handle */
+  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
+  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
+);
+#endif
+
+
+/* C_DecryptInit initializes a decryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
+  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
+);
+#endif
+
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,           /* session's handle */
+  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
+  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
+  CK_BYTE_PTR       pData,              /* gets plaintext */
+  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
+);
+#endif
+
+
+/* C_DecryptUpdate continues a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
+  CK_ULONG          ulEncryptedPartLen,  /* input length */
+  CK_BYTE_PTR       pPart,               /* gets plaintext */
+  CK_ULONG_PTR      pulPartLen           /* p-text size */
+);
+#endif
+
+
+/* C_DecryptFinal finishes a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,       /* the session's handle */
+  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
+  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
+);
+#endif
+
+
+
+/* Message digesting */
+
+/* C_DigestInit initializes a message-digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
+);
+#endif
+
+
+/* C_Digest digests data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Digest)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,     /* the session's handle */
+  CK_BYTE_PTR       pData,        /* data to be digested */
+  CK_ULONG          ulDataLen,    /* bytes of data to digest */
+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
+  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
+);
+#endif
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_BYTE_PTR       pPart,     /* data to be digested */
+  CK_ULONG          ulPartLen  /* bytes of data to be digested */
+);
+#endif
+
+
+/* C_DigestKey continues a multi-part message-digesting
+ * operation, by digesting the value of a secret key as part of
+ * the data already digested. */
+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
+);
+#endif
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,     /* the session's handle */
+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
+  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
+);
+#endif
+
+
+
+/* Signing and MACing */
+
+/* C_SignInit initializes a signature (private key encryption)
+ * operation, where the signature is (will be) an appendix to
+ * the data, and plaintext cannot be recovered from the
+ *signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
+  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
+);
+#endif
+
+
+/* C_Sign signs (encrypts with private key) data in a single
+ * part, where the signature is (will be) an appendix to the
+ * data, and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Sign)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_BYTE_PTR       pData,           /* the data to sign */
+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
+  CK_BYTE_PTR       pSignature,      /* gets the signature */
+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
+);
+#endif
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data, 
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_BYTE_PTR       pPart,     /* the data to sign */
+  CK_ULONG          ulPartLen  /* count of bytes to sign */
+);
+#endif
+
+
+/* C_SignFinal finishes a multiple-part signature operation, 
+ * returning the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_BYTE_PTR       pSignature,      /* gets the signature */
+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
+);
+#endif
+
+
+/* C_SignRecoverInit initializes a signature operation, where
+ * the data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,   /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
+  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
+);
+#endif
+
+
+/* C_SignRecover signs data in a single operation, where the
+ * data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_BYTE_PTR       pData,           /* the data to sign */
+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
+  CK_BYTE_PTR       pSignature,      /* gets the signature */
+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
+);
+#endif
+
+
+
+/* Verifying signatures and MACs */
+
+/* C_VerifyInit initializes a verification operation, where the
+ * signature is an appendix to the data, and plaintext cannot
+ *  cannot be recovered from the signature (e.g. DSA). */
+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
+  CK_OBJECT_HANDLE  hKey         /* verification key */ 
+);
+#endif
+
+
+/* C_Verify verifies a signature in a single-part operation, 
+ * where the signature is an appendix to the data, and plaintext
+ * cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Verify)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,       /* the session's handle */
+  CK_BYTE_PTR       pData,          /* signed data */
+  CK_ULONG          ulDataLen,      /* length of signed data */
+  CK_BYTE_PTR       pSignature,     /* signature */
+  CK_ULONG          ulSignatureLen  /* signature length*/
+);
+#endif
+
+
+/* C_VerifyUpdate continues a multiple-part verification
+ * operation, where the signature is an appendix to the data, 
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_BYTE_PTR       pPart,     /* signed data */
+  CK_ULONG          ulPartLen  /* length of signed data */
+);
+#endif
+
+
+/* C_VerifyFinal finishes a multiple-part verification
+ * operation, checking the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,       /* the session's handle */
+  CK_BYTE_PTR       pSignature,     /* signature to verify */
+  CK_ULONG          ulSignatureLen  /* signature length */
+);
+#endif
+
+
+/* C_VerifyRecoverInit initializes a signature verification
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
+  CK_OBJECT_HANDLE  hKey         /* verification key */
+);
+#endif
+
+
+/* C_VerifyRecover verifies a signature in a single-part
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_BYTE_PTR       pSignature,      /* signature to verify */
+  CK_ULONG          ulSignatureLen,  /* signature length */
+  CK_BYTE_PTR       pData,           /* gets signed data */
+  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
+);
+#endif
+
+
+
+/* Dual-function cryptographic operations */
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting
+ * and encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pPart,               /* the plaintext data */
+  CK_ULONG          ulPartLen,           /* plaintext length */
+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
+ * digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
+  CK_BYTE_PTR       pPart,               /* gets plaintext */
+  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
+);
+#endif
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and
+ * encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pPart,               /* the plaintext data */
+  CK_ULONG          ulPartLen,           /* plaintext length */
+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
+ * verify operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,            /* session's handle */
+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
+  CK_BYTE_PTR       pPart,               /* gets plaintext */
+  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
+);
+#endif
+
+
+
+/* Key management */
+
+/* C_GenerateKey generates a secret key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
+  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
+  CK_ULONG             ulCount,     /* # of attrs in template */
+  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
+);
+#endif
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair, 
+ * creating new key objects. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,                    /* session
+                                                     * handle */
+  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
+                                                     * mech. */
+  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
+                                                     * for pub.
+                                                     * key */
+  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
+                                                     * attrs. */
+  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
+                                                     * for priv.
+                                                     * key */
+  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
+                                                     * attrs. */
+  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
+                                                     * key
+                                                     * handle */
+  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
+                                                     * priv. key
+                                                     * handle */
+);
+#endif
+
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,        /* the session's handle */
+  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
+  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
+  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
+  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
+  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
+);
+#endif
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+ * key object. */
+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,          /* session's handle */
+  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
+  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
+  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
+  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
+  CK_ULONG             ulAttributeCount,  /* template length */
+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
+);
+#endif
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE    hSession,          /* session's handle */
+  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
+  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
+  CK_ULONG             ulAttributeCount,  /* template length */
+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
+);
+#endif
+
+
+
+/* Random number generation */
+
+/* C_SeedRandom mixes additional seed material into the token's
+ * random number generator. */
+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,  /* the session's handle */
+  CK_BYTE_PTR       pSeed,     /* the seed material */
+  CK_ULONG          ulSeedLen  /* length of seed material */
+);
+#endif
+
+
+/* C_GenerateRandom generates random data. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession,    /* the session's handle */
+  CK_BYTE_PTR       RandomData,  /* receives the random data */
+  CK_ULONG          ulRandomLen  /* # of bytes to generate */
+);
+#endif
+
+
+
+/* Parallel function management */
+
+/* C_GetFunctionStatus is a legacy function; it obtains an
+ * updated status of a function running in parallel with an
+ * application. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+/* C_CancelFunction is a legacy function; it cancels a function
+ * running in parallel. */
+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_SESSION_HANDLE hSession  /* the session's handle */
+);
+#endif
+
+
+
+/* Functions added in for Cryptoki Version 2.01 or later */
+
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
+ * removal, etc.) to occur. */
+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
+#ifdef CK_NEED_ARG_LIST
+(
+  CK_FLAGS flags,        /* blocking/nonblocking flag */
+  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
+  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
+);
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/pkcs11t.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/pkcs11t.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/pkcs11t.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,1440 @@
+/* pkcs11t.h include file for PKCS #11. */
+/* $Revision: 1.4 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki)" in all material mentioning or referencing this software.
+
+ * License is also granted to make and use derivative works provided that
+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
+ * referencing the derived work.
+
+ * RSA Security Inc. makes no representations concerning either the 
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* See top of pkcs11.h for information about the macros that
+ * must be defined and the structure-packing conventions that
+ * must be set before including this file. */
+
+#ifndef _PKCS11T_H_
+#define _PKCS11T_H_ 1
+
+#ifndef CK_DISABLE_TRUE_FALSE
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE !(FALSE)
+#endif
+#endif
+
+#define CK_TRUE 1
+#define CK_FALSE 0
+
+/* an unsigned 8-bit value */
+typedef unsigned char     CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE           CK_CHAR;
+
+/* an 8-bit UTF-8 character */
+typedef CK_BYTE           CK_UTF8CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef CK_BYTE           CK_BBOOL;
+
+/* an unsigned value, at least 32 bits long */
+typedef unsigned long int CK_ULONG;
+
+/* a signed value, the same size as a CK_ULONG */
+/* CK_LONG is new for v2.0 */
+typedef long int          CK_LONG;
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef CK_ULONG          CK_FLAGS;
+
+
+/* some special values for certain CK_ULONG variables */
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
+#define CK_EFFECTIVELY_INFINITE    0
+
+
+typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
+typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
+typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
+typedef void        CK_PTR   CK_VOID_PTR;
+
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
+
+
+/* The following value is always invalid if used as a session */
+/* handle or object handle */
+#define CK_INVALID_HANDLE 0
+
+
+typedef struct CK_VERSION {
+  CK_BYTE       major;  /* integer portion of version number */
+  CK_BYTE       minor;  /* 1/100ths portion of version number */
+} CK_VERSION;
+
+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
+
+
+typedef struct CK_INFO {
+  /* manufacturerID and libraryDecription have been changed from
+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
+  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
+  CK_FLAGS      flags;               /* must be zero */
+
+  /* libraryDescription and libraryVersion are new for v2.0 */
+  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
+  CK_VERSION    libraryVersion;          /* version of library */
+} CK_INFO;
+
+typedef CK_INFO CK_PTR    CK_INFO_PTR;
+
+
+/* CK_NOTIFICATION enumerates the types of notifications that
+ * Cryptoki provides to an application */
+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_NOTIFICATION;
+#define CKN_SURRENDER       0
+
+
+typedef CK_ULONG          CK_SLOT_ID;
+
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
+
+
+/* CK_SLOT_INFO provides information about a slot */
+typedef struct CK_SLOT_INFO {
+  /* slotDescription and manufacturerID have been changed from
+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
+  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
+  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
+  CK_FLAGS      flags;
+
+  /* hardwareVersion and firmwareVersion are new for v2.0 */
+  CK_VERSION    hardwareVersion;  /* version of hardware */
+  CK_VERSION    firmwareVersion;  /* version of firmware */
+} CK_SLOT_INFO;
+
+/* flags: bit flags that provide capabilities of the slot
+ *      Bit Flag              Mask        Meaning
+ */
+#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
+#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
+#define CKF_HW_SLOT           0x00000004  /* hardware slot */
+
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
+
+
+/* CK_TOKEN_INFO provides information about a token */
+typedef struct CK_TOKEN_INFO {
+  /* label, manufacturerID, and model have been changed from
+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
+  CK_UTF8CHAR   label[32];           /* blank padded */
+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
+  CK_UTF8CHAR   model[16];           /* blank padded */
+  CK_CHAR       serialNumber[16];    /* blank padded */
+  CK_FLAGS      flags;               /* see below */
+
+  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
+   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
+   * changed from CK_USHORT to CK_ULONG for v2.0 */
+  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
+  CK_ULONG      ulSessionCount;        /* sess. now open */
+  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
+  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
+  CK_ULONG      ulMaxPinLen;           /* in bytes */
+  CK_ULONG      ulMinPinLen;           /* in bytes */
+  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
+  CK_ULONG      ulFreePublicMemory;    /* in bytes */
+  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
+  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
+
+  /* hardwareVersion, firmwareVersion, and time are new for
+   * v2.0 */
+  CK_VERSION    hardwareVersion;       /* version of hardware */
+  CK_VERSION    firmwareVersion;       /* version of firmware */
+  CK_CHAR       utcTime[16];           /* time */
+} CK_TOKEN_INFO;
+
+/* The flags parameter is defined as follows:
+ *      Bit Flag                    Mask        Meaning 
+ */
+#define CKF_RNG                     0x00000001  /* has random #
+                                                 * generator */
+#define CKF_WRITE_PROTECTED         0x00000002  /* token is
+                                                 * write-
+                                                 * protected */
+#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
+                                                 * login */
+#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
+                                                 * PIN is set */
+
+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
+ * that means that *every* time the state of cryptographic
+ * operations of a session is successfully saved, all keys
+ * needed to continue those operations are stored in the state */
+#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
+
+/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
+ * that the token has some sort of clock.  The time on that
+ * clock is returned in the token info structure */
+#define CKF_CLOCK_ON_TOKEN          0x00000040
+
+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
+ * set, that means that there is some way for the user to login
+ * without sending a PIN through the Cryptoki library itself */
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
+
+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
+ * that means that a single session with the token can perform
+ * dual simultaneous cryptographic operations (digest and
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
+ * and sign) */
+#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
+
+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
+ * token has been initialized using C_InitializeToken or an 
+ * equivalent mechanism outside the scope of PKCS #11.
+ * Calling C_InitializeToken when this flag is set will cause 
+ * the token to be reinitialized. */
+#define CKF_TOKEN_INITIALIZED       0x00000400
+
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is 
+ * true, the token supports secondary authentication for 
+ * private key objects. */
+#define CKF_SECONDARY_AUTHENTICATION  0x00000800
+
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an 
+ * incorrect user login PIN has been entered at least once 
+ * since the last successful authentication. */
+#define CKF_USER_PIN_COUNT_LOW       0x00010000
+
+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect user PIN will it to become locked. */
+#define CKF_USER_PIN_FINAL_TRY       0x00020000
+
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the 
+ * user PIN has been locked. User login to the token is not 
+ * possible. */
+#define CKF_USER_PIN_LOCKED          0x00040000
+
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true, 
+ * the user PIN value is the default value set by token 
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
+
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an 
+ * incorrect SO login PIN has been entered at least once since 
+ * the last successful authentication. */
+#define CKF_SO_PIN_COUNT_LOW         0x00100000
+
+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect SO PIN will it to become locked. */
+#define CKF_SO_PIN_FINAL_TRY         0x00200000
+
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO 
+ * PIN has been locked. SO login to the token is not possible.
+ */
+#define CKF_SO_PIN_LOCKED            0x00400000
+
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true, 
+ * the SO PIN value is the default value set by token 
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
+
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
+
+
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
+ * identifies a session */
+typedef CK_ULONG          CK_SESSION_HANDLE;
+
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR; 
+
+
+/* CK_USER_TYPE enumerates the types of Cryptoki users */
+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_USER_TYPE;
+/* Security Officer */
+#define CKU_SO    0
+/* Normal user */
+#define CKU_USER  1
+
+
+/* CK_STATE enumerates the session states */
+/* CK_STATE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_STATE;
+#define CKS_RO_PUBLIC_SESSION  0
+#define CKS_RO_USER_FUNCTIONS  1
+#define CKS_RW_PUBLIC_SESSION  2
+#define CKS_RW_USER_FUNCTIONS  3
+#define CKS_RW_SO_FUNCTIONS    4
+
+
+/* CK_SESSION_INFO provides information about a session */
+typedef struct CK_SESSION_INFO {
+  CK_SLOT_ID    slotID;
+  CK_STATE      state;
+  CK_FLAGS      flags;          /* see below */
+
+  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
+   * v2.0 */
+  CK_ULONG      ulDeviceError;  /* device-dependent error code */
+} CK_SESSION_INFO;
+
+/* The flags are defined in the following table:
+ *      Bit Flag                Mask        Meaning
+ */
+#define CKF_RW_SESSION          0x00000002  /* session is r/w */
+#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
+
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
+
+
+/* CK_OBJECT_HANDLE is a token-specific identifier for an
+ * object  */
+typedef CK_ULONG          CK_OBJECT_HANDLE;
+
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
+
+
+/* CK_OBJECT_CLASS is a value that identifies the classes (or
+ * types) of objects that Cryptoki recognizes.  It is defined
+ * as follows: */
+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_OBJECT_CLASS;
+
+/* The following classes of objects are defined: */
+/* CKO_HW_FEATURE is new for v2.10 */
+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
+#define CKO_DATA              0x00000000
+#define CKO_CERTIFICATE       0x00000001
+#define CKO_PUBLIC_KEY        0x00000002
+#define CKO_PRIVATE_KEY       0x00000003
+#define CKO_SECRET_KEY        0x00000004
+#define CKO_HW_FEATURE        0x00000005
+#define CKO_DOMAIN_PARAMETERS 0x00000006
+#define CKO_VENDOR_DEFINED    0x80000000
+
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
+ * value that identifies the hardware feature type of an object
+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
+typedef CK_ULONG          CK_HW_FEATURE_TYPE;
+ 
+/* The following hardware feature types are defined */
+#define CKH_MONOTONIC_COUNTER  0x00000001
+#define CKH_CLOCK           0x00000002
+#define CKH_VENDOR_DEFINED  0x80000000
+
+/* CK_KEY_TYPE is a value that identifies a key type */
+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG          CK_KEY_TYPE;
+
+/* the following key types are defined: */
+#define CKK_RSA             0x00000000
+#define CKK_DSA             0x00000001
+#define CKK_DH              0x00000002
+
+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
+#define CKK_ECDSA           0x00000003
+#define CKK_EC              0x00000003
+#define CKK_X9_42_DH        0x00000004
+#define CKK_KEA             0x00000005
+
+#define CKK_GENERIC_SECRET  0x00000010
+#define CKK_RC2             0x00000011
+#define CKK_RC4             0x00000012
+#define CKK_DES             0x00000013
+#define CKK_DES2            0x00000014
+#define CKK_DES3            0x00000015
+
+/* all these key types are new for v2.0 */
+#define CKK_CAST            0x00000016
+#define CKK_CAST3           0x00000017
+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
+#define CKK_CAST5           0x00000018
+#define CKK_CAST128         0x00000018
+#define CKK_RC5             0x00000019
+#define CKK_IDEA            0x0000001A
+#define CKK_SKIPJACK        0x0000001B
+#define CKK_BATON           0x0000001C
+#define CKK_JUNIPER         0x0000001D
+#define CKK_CDMF            0x0000001E
+#define CKK_AES             0x0000001F
+
+#define CKK_VENDOR_DEFINED  0x80000000
+
+
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
+ * type */
+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG          CK_CERTIFICATE_TYPE;
+
+/* The following certificate types are defined: */
+/* CKC_X_509_ATTR_CERT is new for v2.10 */
+#define CKC_X_509           0x00000000
+#define CKC_X_509_ATTR_CERT 0x00000001
+#define CKC_VENDOR_DEFINED  0x80000000
+
+
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
+ * type */
+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
+
+/* The following attribute types are defined: */
+#define CKA_CLASS              0x00000000
+#define CKA_TOKEN              0x00000001
+#define CKA_PRIVATE            0x00000002
+#define CKA_LABEL              0x00000003
+#define CKA_APPLICATION        0x00000010
+#define CKA_VALUE              0x00000011
+
+/* CKA_OBJECT_ID is new for v2.10 */
+#define CKA_OBJECT_ID          0x00000012
+
+#define CKA_CERTIFICATE_TYPE   0x00000080
+#define CKA_ISSUER             0x00000081
+#define CKA_SERIAL_NUMBER      0x00000082
+
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new 
+ * for v2.10 */
+#define CKA_AC_ISSUER          0x00000083
+#define CKA_OWNER              0x00000084
+#define CKA_ATTR_TYPES         0x00000085
+
+/* CKA_TRUSTED is new for v2.11 */
+#define CKA_TRUSTED            0x00000086
+
+#define CKA_KEY_TYPE           0x00000100
+#define CKA_SUBJECT            0x00000101
+#define CKA_ID                 0x00000102
+#define CKA_SENSITIVE          0x00000103
+#define CKA_ENCRYPT            0x00000104
+#define CKA_DECRYPT            0x00000105
+#define CKA_WRAP               0x00000106
+#define CKA_UNWRAP             0x00000107
+#define CKA_SIGN               0x00000108
+#define CKA_SIGN_RECOVER       0x00000109
+#define CKA_VERIFY             0x0000010A
+#define CKA_VERIFY_RECOVER     0x0000010B
+#define CKA_DERIVE             0x0000010C
+#define CKA_START_DATE         0x00000110
+#define CKA_END_DATE           0x00000111
+#define CKA_MODULUS            0x00000120
+#define CKA_MODULUS_BITS       0x00000121
+#define CKA_PUBLIC_EXPONENT    0x00000122
+#define CKA_PRIVATE_EXPONENT   0x00000123
+#define CKA_PRIME_1            0x00000124
+#define CKA_PRIME_2            0x00000125
+#define CKA_EXPONENT_1         0x00000126
+#define CKA_EXPONENT_2         0x00000127
+#define CKA_COEFFICIENT        0x00000128
+#define CKA_PRIME              0x00000130
+#define CKA_SUBPRIME           0x00000131
+#define CKA_BASE               0x00000132
+
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
+#define CKA_PRIME_BITS         0x00000133
+#define CKA_SUBPRIME_BITS      0x00000134 
+#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS 
+/* (To retain backwards-compatibility) */
+
+#define CKA_VALUE_BITS         0x00000160
+#define CKA_VALUE_LEN          0x00000161
+
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
+ * and CKA_EC_POINT are new for v2.0 */
+#define CKA_EXTRACTABLE        0x00000162
+#define CKA_LOCAL              0x00000163
+#define CKA_NEVER_EXTRACTABLE  0x00000164
+#define CKA_ALWAYS_SENSITIVE   0x00000165
+
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
+#define CKA_KEY_GEN_MECHANISM  0x00000166
+
+#define CKA_MODIFIABLE         0x00000170
+
+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
+ * CKA_EC_PARAMS is preferred. */
+#define CKA_ECDSA_PARAMS       0x00000180
+#define CKA_EC_PARAMS          0x00000180
+
+#define CKA_EC_POINT           0x00000181
+
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS, 
+ * CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
+ * are new for v2.10 */
+#define CKA_SECONDARY_AUTH     0x00000200
+#define CKA_AUTH_PIN_FLAGS     0x00000201
+#define CKA_HW_FEATURE_TYPE    0x00000300
+#define CKA_RESET_ON_INIT      0x00000301
+#define CKA_HAS_RESET          0x00000302
+
+#define CKA_VENDOR_DEFINED     0x80000000
+
+
+/* CK_ATTRIBUTE is a structure that includes the type, length
+ * and value of an attribute */
+typedef struct CK_ATTRIBUTE {
+  CK_ATTRIBUTE_TYPE type;
+  CK_VOID_PTR       pValue;
+
+  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
+  CK_ULONG          ulValueLen;  /* in bytes */
+} CK_ATTRIBUTE;
+
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
+
+
+/* CK_DATE is a structure that defines a date */
+typedef struct CK_DATE{
+  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
+  CK_CHAR       month[2];  /* the month ("01" - "12") */
+  CK_CHAR       day[2];    /* the day   ("01" - "31") */
+} CK_DATE;
+
+
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
+ * type */
+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG          CK_MECHANISM_TYPE;
+
+/* the following mechanism types are defined: */
+#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
+#define CKM_RSA_PKCS                   0x00000001
+#define CKM_RSA_9796                   0x00000002
+#define CKM_RSA_X_509                  0x00000003
+
+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
+ * are new for v2.0.  They are mechanisms which hash and sign */
+#define CKM_MD2_RSA_PKCS               0x00000004
+#define CKM_MD5_RSA_PKCS               0x00000005
+#define CKM_SHA1_RSA_PKCS              0x00000006
+
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
+#define CKM_RIPEMD128_RSA_PKCS         0x00000007
+#define CKM_RIPEMD160_RSA_PKCS         0x00000008
+#define CKM_RSA_PKCS_OAEP              0x00000009
+
+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
+#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
+#define CKM_RSA_X9_31                  0x0000000B
+#define CKM_SHA1_RSA_X9_31             0x0000000C
+#define CKM_RSA_PKCS_PSS               0x0000000D
+#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
+
+#define CKM_DSA_KEY_PAIR_GEN           0x00000010
+#define CKM_DSA                        0x00000011
+#define CKM_DSA_SHA1                   0x00000012
+#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
+#define CKM_DH_PKCS_DERIVE             0x00000021
+
+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
+ * v2.11 */
+#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
+#define CKM_X9_42_DH_DERIVE            0x00000031
+#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
+#define CKM_X9_42_MQV_DERIVE           0x00000033
+
+#define CKM_RC2_KEY_GEN                0x00000100
+#define CKM_RC2_ECB                    0x00000101
+#define CKM_RC2_CBC                    0x00000102
+#define CKM_RC2_MAC                    0x00000103
+
+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
+#define CKM_RC2_MAC_GENERAL            0x00000104
+#define CKM_RC2_CBC_PAD                0x00000105
+
+#define CKM_RC4_KEY_GEN                0x00000110
+#define CKM_RC4                        0x00000111
+#define CKM_DES_KEY_GEN                0x00000120
+#define CKM_DES_ECB                    0x00000121
+#define CKM_DES_CBC                    0x00000122
+#define CKM_DES_MAC                    0x00000123
+
+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
+#define CKM_DES_MAC_GENERAL            0x00000124
+#define CKM_DES_CBC_PAD                0x00000125
+
+#define CKM_DES2_KEY_GEN               0x00000130
+#define CKM_DES3_KEY_GEN               0x00000131
+#define CKM_DES3_ECB                   0x00000132
+#define CKM_DES3_CBC                   0x00000133
+#define CKM_DES3_MAC                   0x00000134
+
+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
+#define CKM_DES3_MAC_GENERAL           0x00000135
+#define CKM_DES3_CBC_PAD               0x00000136
+#define CKM_CDMF_KEY_GEN               0x00000140
+#define CKM_CDMF_ECB                   0x00000141
+#define CKM_CDMF_CBC                   0x00000142
+#define CKM_CDMF_MAC                   0x00000143
+#define CKM_CDMF_MAC_GENERAL           0x00000144
+#define CKM_CDMF_CBC_PAD               0x00000145
+
+#define CKM_MD2                        0x00000200
+
+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD2_HMAC                   0x00000201
+#define CKM_MD2_HMAC_GENERAL           0x00000202
+
+#define CKM_MD5                        0x00000210
+
+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD5_HMAC                   0x00000211
+#define CKM_MD5_HMAC_GENERAL           0x00000212
+
+#define CKM_SHA_1                      0x00000220
+
+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
+#define CKM_SHA_1_HMAC                 0x00000221
+#define CKM_SHA_1_HMAC_GENERAL         0x00000222
+
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC, 
+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
+#define CKM_RIPEMD128                  0x00000230
+#define CKM_RIPEMD128_HMAC             0x00000231
+#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
+#define CKM_RIPEMD160                  0x00000240
+#define CKM_RIPEMD160_HMAC             0x00000241
+#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
+
+/* All of the following mechanisms are new for v2.0 */
+/* Note that CAST128 and CAST5 are the same algorithm */
+#define CKM_CAST_KEY_GEN               0x00000300
+#define CKM_CAST_ECB                   0x00000301
+#define CKM_CAST_CBC                   0x00000302
+#define CKM_CAST_MAC                   0x00000303
+#define CKM_CAST_MAC_GENERAL           0x00000304
+#define CKM_CAST_CBC_PAD               0x00000305
+#define CKM_CAST3_KEY_GEN              0x00000310
+#define CKM_CAST3_ECB                  0x00000311
+#define CKM_CAST3_CBC                  0x00000312
+#define CKM_CAST3_MAC                  0x00000313
+#define CKM_CAST3_MAC_GENERAL          0x00000314
+#define CKM_CAST3_CBC_PAD              0x00000315
+#define CKM_CAST5_KEY_GEN              0x00000320
+#define CKM_CAST128_KEY_GEN            0x00000320
+#define CKM_CAST5_ECB                  0x00000321
+#define CKM_CAST128_ECB                0x00000321
+#define CKM_CAST5_CBC                  0x00000322
+#define CKM_CAST128_CBC                0x00000322
+#define CKM_CAST5_MAC                  0x00000323
+#define CKM_CAST128_MAC                0x00000323
+#define CKM_CAST5_MAC_GENERAL          0x00000324
+#define CKM_CAST128_MAC_GENERAL        0x00000324
+#define CKM_CAST5_CBC_PAD              0x00000325
+#define CKM_CAST128_CBC_PAD            0x00000325
+#define CKM_RC5_KEY_GEN                0x00000330
+#define CKM_RC5_ECB                    0x00000331
+#define CKM_RC5_CBC                    0x00000332
+#define CKM_RC5_MAC                    0x00000333
+#define CKM_RC5_MAC_GENERAL            0x00000334
+#define CKM_RC5_CBC_PAD                0x00000335
+#define CKM_IDEA_KEY_GEN               0x00000340
+#define CKM_IDEA_ECB                   0x00000341
+#define CKM_IDEA_CBC                   0x00000342
+#define CKM_IDEA_MAC                   0x00000343
+#define CKM_IDEA_MAC_GENERAL           0x00000344
+#define CKM_IDEA_CBC_PAD               0x00000345
+#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
+#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
+#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
+#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
+#define CKM_XOR_BASE_AND_DATA          0x00000364
+#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
+#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
+#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
+#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
+
+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
+#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
+#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
+#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
+#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
+
+#define CKM_SSL3_MD5_MAC               0x00000380
+#define CKM_SSL3_SHA1_MAC              0x00000381
+#define CKM_MD5_KEY_DERIVATION         0x00000390
+#define CKM_MD2_KEY_DERIVATION         0x00000391
+#define CKM_SHA1_KEY_DERIVATION        0x00000392
+#define CKM_PBE_MD2_DES_CBC            0x000003A0
+#define CKM_PBE_MD5_DES_CBC            0x000003A1
+#define CKM_PBE_MD5_CAST_CBC           0x000003A2
+#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
+#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
+#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
+#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
+#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
+#define CKM_PBE_SHA1_RC4_128           0x000003A6
+#define CKM_PBE_SHA1_RC4_40            0x000003A7
+#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
+#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
+#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
+#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
+
+/* CKM_PKCS5_PBKD2 is new for v2.10 */
+#define CKM_PKCS5_PBKD2                0x000003B0
+
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
+#define CKM_KEY_WRAP_LYNKS             0x00000400
+#define CKM_KEY_WRAP_SET_OAEP          0x00000401
+
+/* Fortezza mechanisms */
+#define CKM_SKIPJACK_KEY_GEN           0x00001000
+#define CKM_SKIPJACK_ECB64             0x00001001
+#define CKM_SKIPJACK_CBC64             0x00001002
+#define CKM_SKIPJACK_OFB64             0x00001003
+#define CKM_SKIPJACK_CFB64             0x00001004
+#define CKM_SKIPJACK_CFB32             0x00001005
+#define CKM_SKIPJACK_CFB16             0x00001006
+#define CKM_SKIPJACK_CFB8              0x00001007
+#define CKM_SKIPJACK_WRAP              0x00001008
+#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
+#define CKM_SKIPJACK_RELAYX            0x0000100a
+#define CKM_KEA_KEY_PAIR_GEN           0x00001010
+#define CKM_KEA_KEY_DERIVE             0x00001011
+#define CKM_FORTEZZA_TIMESTAMP         0x00001020
+#define CKM_BATON_KEY_GEN              0x00001030
+#define CKM_BATON_ECB128               0x00001031
+#define CKM_BATON_ECB96                0x00001032
+#define CKM_BATON_CBC128               0x00001033
+#define CKM_BATON_COUNTER              0x00001034
+#define CKM_BATON_SHUFFLE              0x00001035
+#define CKM_BATON_WRAP                 0x00001036
+
+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
+ * CKM_EC_KEY_PAIR_GEN is preferred */
+#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
+#define CKM_EC_KEY_PAIR_GEN            0x00001040
+
+#define CKM_ECDSA                      0x00001041
+#define CKM_ECDSA_SHA1                 0x00001042
+
+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
+ * are new for v2.11 */
+#define CKM_ECDH1_DERIVE               0x00001050
+#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
+#define CKM_ECMQV_DERIVE               0x00001052
+
+#define CKM_JUNIPER_KEY_GEN            0x00001060
+#define CKM_JUNIPER_ECB128             0x00001061
+#define CKM_JUNIPER_CBC128             0x00001062
+#define CKM_JUNIPER_COUNTER            0x00001063
+#define CKM_JUNIPER_SHUFFLE            0x00001064
+#define CKM_JUNIPER_WRAP               0x00001065
+#define CKM_FASTHASH                   0x00001070
+
+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
+ * new for v2.11 */
+#define CKM_AES_KEY_GEN                0x00001080
+#define CKM_AES_ECB                    0x00001081
+#define CKM_AES_CBC                    0x00001082
+#define CKM_AES_MAC                    0x00001083
+#define CKM_AES_MAC_GENERAL            0x00001084
+#define CKM_AES_CBC_PAD                0x00001085
+#define CKM_DSA_PARAMETER_GEN          0x00002000
+#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
+#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
+
+#define CKM_VENDOR_DEFINED             0x80000000
+
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
+
+
+/* CK_MECHANISM is a structure that specifies a particular
+ * mechanism  */
+typedef struct CK_MECHANISM {
+  CK_MECHANISM_TYPE mechanism;
+  CK_VOID_PTR       pParameter;
+
+  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
+   * v2.0 */
+  CK_ULONG          ulParameterLen;  /* in bytes */
+} CK_MECHANISM;
+
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
+
+
+/* CK_MECHANISM_INFO provides information about a particular
+ * mechanism */
+typedef struct CK_MECHANISM_INFO {
+    CK_ULONG    ulMinKeySize;
+    CK_ULONG    ulMaxKeySize;
+    CK_FLAGS    flags;
+} CK_MECHANISM_INFO;
+
+/* The flags are defined as follows:
+ *      Bit Flag               Mask        Meaning */
+#define CKF_HW                 0x00000001  /* performed by HW */
+
+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
+ * and CKF_DERIVE are new for v2.0.  They specify whether or not
+ * a mechanism can be used for a particular task */
+#define CKF_ENCRYPT            0x00000100
+#define CKF_DECRYPT            0x00000200
+#define CKF_DIGEST             0x00000400
+#define CKF_SIGN               0x00000800
+#define CKF_SIGN_RECOVER       0x00001000
+#define CKF_VERIFY             0x00002000
+#define CKF_VERIFY_RECOVER     0x00004000
+#define CKF_GENERATE           0x00008000
+#define CKF_GENERATE_KEY_PAIR  0x00010000
+#define CKF_WRAP               0x00020000
+#define CKF_UNWRAP             0x00040000
+#define CKF_DERIVE             0x00080000
+
+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
+ * describe a token's EC capabilities not available in mechanism
+ * information. */
+#define CKF_EC_F_P	           0x00100000
+#define CKF_EC_F_2M	           0x00200000
+#define CKF_EC_ECPARAMETERS	   0x00400000
+#define CKF_EC_NAMEDCURVE	   0x00800000
+#define CKF_EC_UNCOMPRESS	   0x01000000
+#define CKF_EC_COMPRESS	       0x02000000
+
+#define CKF_EXTENSION          0x80000000  /* FALSE for 2.01 */
+
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
+
+
+/* CK_RV is a value that identifies the return value of a
+ * Cryptoki function */
+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG          CK_RV;
+
+#define CKR_OK                                0x00000000
+#define CKR_CANCEL                            0x00000001
+#define CKR_HOST_MEMORY                       0x00000002
+#define CKR_SLOT_ID_INVALID                   0x00000003
+
+/* CKR_FLAGS_INVALID was removed for v2.0 */
+
+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
+#define CKR_GENERAL_ERROR                     0x00000005
+#define CKR_FUNCTION_FAILED                   0x00000006
+
+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
+ * and CKR_CANT_LOCK are new for v2.01 */
+#define CKR_ARGUMENTS_BAD                     0x00000007
+#define CKR_NO_EVENT                          0x00000008
+#define CKR_NEED_TO_CREATE_THREADS            0x00000009
+#define CKR_CANT_LOCK                         0x0000000A
+
+#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
+#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
+#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
+#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
+#define CKR_DATA_INVALID                      0x00000020
+#define CKR_DATA_LEN_RANGE                    0x00000021
+#define CKR_DEVICE_ERROR                      0x00000030
+#define CKR_DEVICE_MEMORY                     0x00000031
+#define CKR_DEVICE_REMOVED                    0x00000032
+#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
+#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
+#define CKR_FUNCTION_CANCELED                 0x00000050
+#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
+
+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
+#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
+
+#define CKR_KEY_HANDLE_INVALID                0x00000060
+
+/* CKR_KEY_SENSITIVE was removed for v2.0 */
+
+#define CKR_KEY_SIZE_RANGE                    0x00000062
+#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
+
+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
+ * v2.0 */
+#define CKR_KEY_NOT_NEEDED                    0x00000064
+#define CKR_KEY_CHANGED                       0x00000065
+#define CKR_KEY_NEEDED                        0x00000066
+#define CKR_KEY_INDIGESTIBLE                  0x00000067
+#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
+#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
+#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
+
+#define CKR_MECHANISM_INVALID                 0x00000070
+#define CKR_MECHANISM_PARAM_INVALID           0x00000071
+
+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
+ * were removed for v2.0 */
+#define CKR_OBJECT_HANDLE_INVALID             0x00000082
+#define CKR_OPERATION_ACTIVE                  0x00000090
+#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
+#define CKR_PIN_INCORRECT                     0x000000A0
+#define CKR_PIN_INVALID                       0x000000A1
+#define CKR_PIN_LEN_RANGE                     0x000000A2
+
+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
+#define CKR_PIN_EXPIRED                       0x000000A3
+#define CKR_PIN_LOCKED                        0x000000A4
+
+#define CKR_SESSION_CLOSED                    0x000000B0
+#define CKR_SESSION_COUNT                     0x000000B1
+#define CKR_SESSION_HANDLE_INVALID            0x000000B3
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
+#define CKR_SESSION_READ_ONLY                 0x000000B5
+#define CKR_SESSION_EXISTS                    0x000000B6
+
+/* CKR_SESSION_READ_ONLY_EXISTS and
+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
+#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
+#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
+
+#define CKR_SIGNATURE_INVALID                 0x000000C0
+#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
+#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
+#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
+#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
+#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
+#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
+#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
+#define CKR_USER_NOT_LOGGED_IN                0x00000101
+#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
+#define CKR_USER_TYPE_INVALID                 0x00000103
+
+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
+ * are new to v2.01 */
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
+#define CKR_USER_TOO_MANY_TYPES               0x00000105
+
+#define CKR_WRAPPED_KEY_INVALID               0x00000110
+#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
+#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
+#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
+#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
+
+/* These are new to v2.0 */
+#define CKR_RANDOM_NO_RNG                     0x00000121
+
+/* These are new to v2.11 */
+#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
+
+/* These are new to v2.0 */
+#define CKR_BUFFER_TOO_SMALL                  0x00000150
+#define CKR_SAVED_STATE_INVALID               0x00000160
+#define CKR_INFORMATION_SENSITIVE             0x00000170
+#define CKR_STATE_UNSAVEABLE                  0x00000180
+
+/* These are new to v2.01 */
+#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
+#define CKR_MUTEX_BAD                         0x000001A0
+#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
+
+#define CKR_VENDOR_DEFINED                    0x80000000
+
+
+/* CK_NOTIFY is an application callback that processes events */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
+  CK_SESSION_HANDLE hSession,     /* the session's handle */
+  CK_NOTIFICATION   event,
+  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
+);
+
+
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
+ * version and pointers of appropriate types to all the
+ * Cryptoki functions */
+/* CK_FUNCTION_LIST is new for v2.0 */
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
+
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
+
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
+
+
+/* CK_CREATEMUTEX is an application callback for creating a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
+  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
+);
+
+
+/* CK_DESTROYMUTEX is an application callback for destroying a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
+  CK_VOID_PTR pMutex  /* pointer to mutex */
+);
+
+
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
+  CK_VOID_PTR pMutex  /* pointer to mutex */
+);
+
+
+/* CK_UNLOCKMUTEX is an application callback for unlocking a
+ * mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
+  CK_VOID_PTR pMutex  /* pointer to mutex */
+);
+
+
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
+ * C_Initialize */
+typedef struct CK_C_INITIALIZE_ARGS {
+  CK_CREATEMUTEX CreateMutex;
+  CK_DESTROYMUTEX DestroyMutex;
+  CK_LOCKMUTEX LockMutex;
+  CK_UNLOCKMUTEX UnlockMutex;
+  CK_FLAGS flags;
+  CK_VOID_PTR pReserved;
+} CK_C_INITIALIZE_ARGS;
+
+/* flags: bit flags that provide capabilities of the slot
+ *      Bit Flag                           Mask       Meaning
+ */
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
+#define CKF_OS_LOCKING_OK                  0x00000002
+
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
+
+
+/* additional flags for parameters to functions */
+
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+#define CKF_DONT_BLOCK     1
+
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10. 
+ * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message 
+ * Generation Function (MGF) applied to a message block when 
+ * formatting a message block for the PKCS #1 OAEP encryption 
+ * scheme. */
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
+
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
+
+/* The following MGFs are defined */
+#define CKG_MGF1_SHA1         0x00000001
+
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10. 
+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
+ * of the encoding parameter when formatting a message block 
+ * for the PKCS #1 OAEP encryption scheme. */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+/* The following encoding parameter sources are defined */
+#define CKZ_DATA_SPECIFIED    0x00000001
+
+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the 
+ * CKM_RSA_PKCS_OAEP mechanism. */
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+	CK_MECHANISM_TYPE hashAlg;
+	CK_RSA_PKCS_MGF_TYPE mgf;
+	CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+	CK_VOID_PTR pSourceData;
+	CK_ULONG ulSourceDataLen;
+} CK_RSA_PKCS_OAEP_PARAMS;
+
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
+
+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_PSS mechanism(s). */
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+	CK_MECHANISM_TYPE    hashAlg;
+	CK_RSA_PKCS_MGF_TYPE mgf;
+	CK_ULONG             sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
+
+/* CK_EC_KDF_TYPE is new for v2.11. */
+typedef CK_ULONG CK_EC_KDF_TYPE;
+
+/* The following EC Key Derivation Functions are defined */
+#define CKD_NULL                 0x00000001
+#define CKD_SHA1_KDF             0x00000002
+
+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
+ * where each party contributes one key pair.
+ */
+typedef struct CK_ECDH1_DERIVE_PARAMS {
+  CK_EC_KDF_TYPE kdf;
+  CK_ULONG ulSharedDataLen;
+  CK_BYTE_PTR pSharedData;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+} CK_ECDH1_DERIVE_PARAMS;
+
+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
+
+
+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
+typedef struct CK_ECDH2_DERIVE_PARAMS {
+  CK_EC_KDF_TYPE kdf;
+  CK_ULONG ulSharedDataLen;
+  CK_BYTE_PTR pSharedData;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+  CK_ULONG ulPrivateDataLen;
+  CK_OBJECT_HANDLE hPrivateData;
+  CK_ULONG ulPublicDataLen2;
+  CK_BYTE_PTR pPublicData2;
+} CK_ECDH2_DERIVE_PARAMS;
+
+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
+
+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the 
+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
+
+/* The following X9.42 DH key derivation functions are defined: */
+#define CKD_NULL                 0x00000001
+#define CKD_SHA1_KDF_ASN1        0x00000003
+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
+
+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the 
+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
+ * contributes one key pair */
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
+  CK_X9_42_DH_KDF_TYPE kdf;
+  CK_ULONG ulOtherInfoLen;
+  CK_BYTE_PTR pOtherInfo;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+} CK_X9_42_DH1_DERIVE_PARAMS;
+
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
+
+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the 
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
+ * mechanisms, where each party contributes two key pairs */
+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
+  CK_X9_42_DH_KDF_TYPE kdf;
+  CK_ULONG ulOtherInfoLen;
+  CK_BYTE_PTR pOtherInfo;
+  CK_ULONG ulPublicDataLen;
+  CK_BYTE_PTR pPublicData;
+  CK_ULONG ulPrivateDataLen;
+  CK_OBJECT_HANDLE hPrivateData;
+  CK_ULONG ulPublicDataLen2;
+  CK_BYTE_PTR pPublicData2;
+} CK_X9_42_DH2_DERIVE_PARAMS;
+
+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
+
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
+ * CKM_KEA_DERIVE mechanism */
+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
+typedef struct CK_KEA_DERIVE_PARAMS {
+  CK_BBOOL      isSender;
+  CK_ULONG      ulRandomLen;
+  CK_BYTE_PTR   pRandomA;
+  CK_BYTE_PTR   pRandomB;
+  CK_ULONG      ulPublicDataLen;
+  CK_BYTE_PTR   pPublicData;
+} CK_KEA_DERIVE_PARAMS;
+
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
+
+
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
+ * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
+ * holds the effective keysize */
+typedef CK_ULONG          CK_RC2_PARAMS;
+
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
+
+
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
+ * mechanism */
+typedef struct CK_RC2_CBC_PARAMS {
+  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
+   * v2.0 */
+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
+
+  CK_BYTE       iv[8];            /* IV for CBC mode */
+} CK_RC2_CBC_PARAMS;
+
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
+
+
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC2_MAC_GENERAL mechanism */
+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
+  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
+} CK_RC2_MAC_GENERAL_PARAMS;
+
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
+  CK_RC2_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
+ * CKM_RC5_MAC mechanisms */
+/* CK_RC5_PARAMS is new for v2.0 */
+typedef struct CK_RC5_PARAMS {
+  CK_ULONG      ulWordsize;  /* wordsize in bits */
+  CK_ULONG      ulRounds;    /* number of rounds */
+} CK_RC5_PARAMS;
+
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
+
+
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
+ * mechanism */
+/* CK_RC5_CBC_PARAMS is new for v2.0 */
+typedef struct CK_RC5_CBC_PARAMS {
+  CK_ULONG      ulWordsize;  /* wordsize in bits */
+  CK_ULONG      ulRounds;    /* number of rounds */
+  CK_BYTE_PTR   pIv;         /* pointer to IV */
+  CK_ULONG      ulIvLen;     /* length of IV in bytes */
+} CK_RC5_CBC_PARAMS;
+
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
+
+
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC5_MAC_GENERAL mechanism */
+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
+  CK_ULONG      ulWordsize;   /* wordsize in bits */
+  CK_ULONG      ulRounds;     /* number of rounds */
+  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
+} CK_RC5_MAC_GENERAL_PARAMS;
+
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
+  CK_RC5_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
+ * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
+ * the MAC */
+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+  CK_ULONG      ulPasswordLen;
+  CK_BYTE_PTR   pPassword;
+  CK_ULONG      ulPublicDataLen;
+  CK_BYTE_PTR   pPublicData;
+  CK_ULONG      ulPAndGLen;
+  CK_ULONG      ulQLen;
+  CK_ULONG      ulRandomLen;
+  CK_BYTE_PTR   pRandomA;
+  CK_BYTE_PTR   pPrimeP;
+  CK_BYTE_PTR   pBaseG;
+  CK_BYTE_PTR   pSubprimeQ;
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
+  CK_SKIPJACK_PRIVATE_WRAP_PTR;
+
+
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_RELAYX mechanism */
+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
+  CK_ULONG      ulOldWrappedXLen;
+  CK_BYTE_PTR   pOldWrappedX;
+  CK_ULONG      ulOldPasswordLen;
+  CK_BYTE_PTR   pOldPassword;
+  CK_ULONG      ulOldPublicDataLen;
+  CK_BYTE_PTR   pOldPublicData;
+  CK_ULONG      ulOldRandomLen;
+  CK_BYTE_PTR   pOldRandomA;
+  CK_ULONG      ulNewPasswordLen;
+  CK_BYTE_PTR   pNewPassword;
+  CK_ULONG      ulNewPublicDataLen;
+  CK_BYTE_PTR   pNewPublicData;
+  CK_ULONG      ulNewRandomLen;
+  CK_BYTE_PTR   pNewRandomA;
+} CK_SKIPJACK_RELAYX_PARAMS;
+
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
+  CK_SKIPJACK_RELAYX_PARAMS_PTR;
+
+
+typedef struct CK_PBE_PARAMS {
+  CK_BYTE_PTR      pInitVector;
+  CK_UTF8CHAR_PTR  pPassword;
+  CK_ULONG         ulPasswordLen;
+  CK_BYTE_PTR      pSalt;
+  CK_ULONG         ulSaltLen;
+  CK_ULONG         ulIteration;
+} CK_PBE_PARAMS;
+
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
+
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
+ * CKM_KEY_WRAP_SET_OAEP mechanism */
+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+  CK_BYTE       bBC;     /* block contents byte */
+  CK_BYTE_PTR   pX;      /* extra data */
+  CK_ULONG      ulXLen;  /* length of extra data in bytes */
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
+  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_RANDOM_DATA {
+  CK_BYTE_PTR  pClientRandom;
+  CK_ULONG     ulClientRandomLen;
+  CK_BYTE_PTR  pServerRandom;
+  CK_ULONG     ulServerRandomLen;
+} CK_SSL3_RANDOM_DATA;
+
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+  CK_SSL3_RANDOM_DATA RandomInfo;
+  CK_VERSION_PTR pVersion;
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_OUT {
+  CK_OBJECT_HANDLE hClientMacSecret;
+  CK_OBJECT_HANDLE hServerMacSecret;
+  CK_OBJECT_HANDLE hClientKey;
+  CK_OBJECT_HANDLE hServerKey;
+  CK_BYTE_PTR      pIVClient;
+  CK_BYTE_PTR      pIVServer;
+} CK_SSL3_KEY_MAT_OUT;
+
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
+  CK_ULONG                ulMacSizeInBits;
+  CK_ULONG                ulKeySizeInBits;
+  CK_ULONG                ulIVSizeInBits;
+  CK_BBOOL                bIsExport;
+  CK_SSL3_RANDOM_DATA     RandomInfo;
+  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_SSL3_KEY_MAT_PARAMS;
+
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+
+
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
+  CK_BYTE_PTR pData;
+  CK_ULONG    ulLen;
+} CK_KEY_DERIVATION_STRING_DATA;
+
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
+  CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+
+/* The CK_EXTRACT_PARAMS is used for the
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
+ * of the base key should be used as the first bit of the
+ * derived key */
+/* CK_EXTRACT_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_EXTRACT_PARAMS;
+
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to 
+ * indicate the Pseudo-Random Function (PRF) used to generate 
+ * key bits using PKCS #5 PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
+/* The following PRFs are defined in PKCS #5 v2.0. */
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
+
+
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the 
+ * source of the salt value when deriving a key using PKCS #5 
+ * PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
+/* The following salt value sources are defined in PKCS #5 v2.0. */
+#define CKZ_SALT_SPECIFIED        0x00000001
+
+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the 
+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
+typedef struct CK_PKCS5_PBKD2_PARAMS {
+	CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
+	CK_VOID_PTR                                pSaltSourceData;
+	CK_ULONG                                   ulSaltSourceDataLen;
+	CK_ULONG                                   iterations;
+	CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+	CK_VOID_PTR                                pPrfData;
+	CK_ULONG                                   ulPrfDataLen;
+	CK_UTF8CHAR_PTR                            pPassword;
+	CK_ULONG_PTR                               ulPasswordLen;
+} CK_PKCS5_PBKD2_PARAMS;
+
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
+#endif
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/zlib/zconf.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/zlib/zconf.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/zlib/zconf.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,332 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_          z_deflateInit_
+#  define deflate               z_deflate
+#  define deflateEnd            z_deflateEnd
+#  define inflateInit_          z_inflateInit_
+#  define inflate               z_inflate
+#  define inflateEnd            z_inflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateCopy           z_deflateCopy
+#  define deflateReset          z_deflateReset
+#  define deflateParams         z_deflateParams
+#  define deflateBound          z_deflateBound
+#  define deflatePrime          z_deflatePrime
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateCopy           z_inflateCopy
+#  define inflateReset          z_inflateReset
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define compress              z_compress
+#  define compress2             z_compress2
+#  define compressBound         z_compressBound
+#  define uncompress            z_uncompress
+#  define adler32               z_adler32
+#  define crc32                 z_crc32
+#  define get_crc_table         z_get_crc_table
+#  define zError                z_zError
+
+#  define alloc_func            z_alloc_func
+#  define free_func             z_free_func
+#  define in_func               z_in_func
+#  define out_func              z_out_func
+#  define Byte                  z_Byte
+#  define uInt                  z_uInt
+#  define uLong                 z_uLong
+#  define Bytef                 z_Bytef
+#  define charf                 z_charf
+#  define intf                  z_intf
+#  define uIntf                 z_uIntf
+#  define uLongf                z_uLongf
+#  define voidpf                z_voidpf
+#  define voidp                 z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if 0           /* HAVE_UNISTD_H -- this line is updated by ./configure */
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  ifdef VMS
+#    include <unixio.h>   /* for off_t */
+#  endif
+#  define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if defined(__OS400__)
+#  define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+#  define NO_vsnprintf
+#  ifdef FAR
+#    undef FAR
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(deflateBound,"DEBND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(compressBound,"CMBND")
+#   pragma map(inflate_table,"INTABL")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
Index: Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/zlib/zlib.h
===================================================================
--- Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/zlib/zlib.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
+++ Dev/utvpn/utvpn-unix-v101-7101-public/src/Mayaqua/zlib/zlib.h	(revision a1bae3ebcd5b813618d88ce3886ee70f73cc87c0)
@@ -0,0 +1,1357 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.3, July 18th, 2005
+
+  Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.3"
+#define ZLIB_VERNUM 0x1230
+
+/*
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms will be added later and will have the same
+  stream interface.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+     The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
+
+     The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+     This library can optionally read and write gzip streams in memory as well.
+
+     The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+     The library does not install any signal handler. The decoder checks
+  the consistency of the compressed data, so the library should never
+  crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: binary or text */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+   This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at
+   all (the input data is simply copied a block at a time).
+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+   compression (currently equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce some
+  output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows. deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumualte before producing output, in order to
+  maximize compression.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far. (In particular
+  avail_in is zero after the call if enough output space has been provided
+  before the call.)  Flushing may degrade compression for some compression
+  algorithms and so it should be used only when necessary.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  the value returned by deflateBound (see below). If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+  fatal, and deflate() can be called again with more input and more output
+  space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression. The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+   value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller.  msg is set to null if there is no error
+   message. inflateInit does not perform any decompression apart from reading
+   the zlib header if present: this will be done by inflate().  (So next_in and
+   avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows. inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+  Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+  if and when it gets to the next deflate block boundary. When decoding the
+  zlib or gzip format, this will cause inflate() to return immediately after
+  the header and before the first block. When doing a raw inflate, inflate()
+  will go ahead and process the first block, and will return when it gets to
+  the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  Also to assist in this, on return inflate() will set strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64
+  if inflate() is currently decoding the last block in the deflate stream,
+  plus 128 if inflate() returned immediately after decoding an end-of-block
+  code or decoding the complete header up to just before the first byte of the
+  deflate stream. The end-of-block will not be indicated until all of the
+  uncompressed data from that block has been written to strm->next_out.  The
+  number of unused bits may in general be greater than seven, except when
+  bit 7 of data_type is set, in which case the number of unused bits will be
+  less than eight.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster approach
+  may be used for the single inflate() call.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call. So the only effect of the flush parameter in this implementation
+  is on the return value of inflate(), as noted below, or when it returns early
+  because Z_BLOCK is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the adler32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the adler32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below. At the end of the stream, inflate() checks that its computed adler32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically.  Any information
+  contained in the gzip header is not retained, so applications that need that
+  information should instead use raw inflate, see inflateInit2() below, or
+  inflateBack() and perform their own processing of the gzip header and
+  trailer.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+  output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing. If Z_DATA_ERROR is returned, the application may then
+  call inflateSync() to look for a good compression block if a partial recovery
+  of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The method parameter is the compression method. It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer). It should be in the range 8..15 for this
+   version of the library. Larger values of this parameter result in better
+   compression at the expense of memory usage. The default value is 15 if
+   deflateInit is used instead.
+
+     windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+   determines the window size. deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute an adler32 check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding. Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper. The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero),
+   no header crc, and the operating system will be set to 255 (unknown).  If a
+   gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding). Filtered data consists mostly of small values with a somewhat
+   random distribution. In this case, the compression algorithm is tuned to
+   compress them better. The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
+   Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
+   parameter only affects the compression ratio but not the correctness of the
+   compressed output even if it is not set appropriately.  Z_FIXED prevents the
+   use of dynamic Huffman codes, allowing for a simpler decoder for special
+   applications.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+   method). msg is set to null if there is no error message.  deflateInit2 does
+   not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output. This function must be called
+   immediately after deflateInit, deflateInit2 or deflateReset, before any
+   call of deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size in
+   deflate or deflate2. Thus the strings most likely to be useful should be
+   put at the end of the dictionary, not at the front. In addition, the
+   current implementation of deflate will use at most the window size minus
+   262 bytes of the provided dictionary.
+
+     Upon return of this function, strm->adler is set to the adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   adler32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort). deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different
+   strategy. If the compression level is changed, the input available so far
+   is compressed with the old level (and may be flushed); the new level will
+   take effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit()
+   or deflateInit2().  This would be used to allocate an output buffer
+   for deflation in a single pass, and so would be called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+  is that this function is used to start off the deflate output with the
+  bits leftover from a previous deflate stream when appending to it.  As such,
+  this function can only be used for raw deflate, and must be used before the
+  first deflate() call after a deflateInit2() or deflateReset().  bits must be
+  less than or equal to 16, and that many of the least significant bits of
+  value will be inserted in the output.
+
+      deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+      deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+      If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+      deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter. The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library. The default value is 15 if inflateInit is used
+   instead. windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used. If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+   determines the window size. inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream. This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values. If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an adler32 or a crc32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is. Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding. Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is
+   a crc32 instead of an adler32.
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
+   is set to null if there is no error message.  inflateInit2 does not perform
+   any decompression apart from reading the zlib header if present: this will
+   be done by inflate(). (So next_in and avail_in may be modified, but next_out
+   and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence. This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
+   can be determined from the adler32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called
+   immediately after inflateInit2() or inflateReset() and before any call of
+   inflate() to set the dictionary.  The application must insure that the
+   dictionary that was used for compression is provided.
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+    Skips invalid compressed data until a full flush point (see above the
+  description of deflate with Z_FULL_FLUSH) can be found, or until all
+  available input is skipped. No output is provided.
+
+    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+  that this function is used to start inflating at a bit position in the
+  middle of a byte.  The provided bits will be used before any bytes are used
+  from next_in.  This function should only be used with raw inflate, and
+  should be used before the first inflate() call after inflateInit2() or
+  inflateReset().  bits must be less than or equal to 16, and that many of the
+  least significant bits of value will be inserted in the input.
+
+      inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+      inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK can be used to
+   force inflate() to return immediately after header processing is complete
+   and before any actual data is decompressed.
+
+      The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.)  If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When
+   any of extra, name, or comment are not Z_NULL and the respective field is
+   not present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+      If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+      inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the paramaters are invalid, Z_MEM_ERROR if the internal state could not
+   be allocated, or Z_VERSION_ERROR if the version of the library does not
+   match the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is more efficient than inflate() for
+   file i/o applications in that it avoids copying between the output and the
+   sliding window by simply making the window itself the output buffer.  This
+   function trusts the application to not change the output buffer passed by
+   the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free
+   the allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects
+   only the raw deflate stream to decompress.  This is different from the
+   normal behavior of inflate(), which expects either a zlib or gzip header and
+   trailer around the deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero--buf is ignored in that
+   case--and inflateBack() will return a buffer error.  inflateBack() will call
+   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()
+   should return zero on success, or non-zero on failure.  If out() returns
+   non-zero, inflateBack() will return with an error.  Neither in() nor out()
+   are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format
+   error in the deflate stream (in which case strm->msg is set to indicate the
+   nature of the error), or Z_STREAM_ERROR if the stream was not properly
+   initialized.  In the case of Z_BUF_ERROR, an input or output error can be
+   distinguished using strm->next_in which will be Z_NULL only if in() returned
+   an error.  If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
+   out() returning non-zero.  (in() will always be called before out(), so
+   strm->next_in is assured to be defined if out() returns non-zero.)  Note
+   that inflateBack() cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the
+   basic stream-oriented functions. To simplify the interface, some
+   default options are assumed (compression level and memory usage,
+   standard memory allocation functions). The source code of these
+   utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least the value returned
+   by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen). Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before
+   a compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
+/*
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb") but can also include a compression level
+   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+   Huffman only compression as in "wb1h", or 'R' for run-length encoding
+   as in "wb1R". (See the description of deflateInit2 for more information
+   about the strategy parameter.)
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.
+
+     gzopen returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).  */
+
+ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
+/*
+     gzdopen() associates a gzFile with the file descriptor fd.  File
+   descriptors are obtained from calls like open, dup, creat, pipe or
+   fileno (in the file has been previously opened with fopen).
+   The mode parameter is as in gzopen.
+     The next call of gzclose on the returned gzFile will also close the
+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+     gzdopen returns NULL if there was insufficient memory to allocate
+   the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy. See the description
+   of deflateInit2 for the meaning of these parameters.
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.
+   If the input file was not in gzip format, gzread copies the given number
+   of bytes into the buffer.
+     gzread returns the number of uncompressed bytes actually read (0 for
+   end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT    gzwrite OF((gzFile file,
+                                   voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes actually written
+   (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).  The number of
+   uncompressed bytes written is limited to 4095. The caller should assure that
+   this limit is not exceeded. If it is exceeded, then gzprintf() will return
+   return an error (0) with nothing written. In this case, there may also be a
+   buffer overflow with unpredictable consequences, which is possible only if
+   zlib was compiled with the insecure functions sprintf() or vsprintf()
+   because the secure snprintf() or vsnprintf() functions were not available.
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+      Reads bytes from the compressed file until len-1 characters are read, or
+   a newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  The string is then terminated with a null
+   character.
+      gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
+/*
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
+/*
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT    gzungetc OF((int c, gzFile file));
+/*
+      Push one character back onto the stream to be read again later.
+   Only one character of push-back is allowed.  gzungetc() returns the
+   character pushed, or -1 on failure.  gzungetc() will fail if a
+   character has been pushed but not read yet, or if c is -1. The pushed
+   character will be discarded if the stream is repositioned with gzseek()
+   or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function. The return value is the zlib
+   error number (see function gzerror below). gzflush returns Z_OK if
+   the flush parameter is Z_FINISH and all output could be flushed.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
+                                      z_off_t offset, int whence));
+/*
+      Sets the starting position for the next gzread or gzwrite on the
+   given compressed file. The offset represents a number of bytes in the
+   uncompressed data stream. The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow. If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+/*
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+
+   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns 1 if file is being read directly without decompression, otherwise
+   zero.
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state. The return value is the zlib
+   error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file. This is analogous to the
+   clearerr() function in stdio. This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the
+   compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+/*
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32. If buf is NULL, this function returns the required initial
+   value for the for the crc. Pre- and post-conditioning (one's complement) is
+   performed within this function so it shouldn't be done by the application.
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+/*
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+        inflateBackInit_((strm), (windowBits), (window), \
+        ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
