OSDN Git Service

Move *.c and *.h files to src
[ffftp/ffftp.git] / src / connect.c
diff --git a/src/connect.c b/src/connect.c
new file mode 100644 (file)
index 0000000..7b390b7
--- /dev/null
@@ -0,0 +1,3437 @@
+/*=============================================================================\r
+*\r
+*                                                              ホストへの接続/切断\r
+*\r
+===============================================================================\r
+/ Copyright (C) 1997-2007 Sota. All rights reserved.\r
+/\r
+/ Redistribution and use in source and binary forms, with or without \r
+/ modification, are permitted provided that the following conditions \r
+/ are met:\r
+/\r
+/  1. Redistributions of source code must retain the above copyright \r
+/     notice, this list of conditions and the following disclaimer.\r
+/  2. Redistributions in binary form must reproduce the above copyright \r
+/     notice, this list of conditions and the following disclaimer in the \r
+/     documentation and/or other materials provided with the distribution.\r
+/\r
+/ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR \r
+/ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES \r
+/ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+/ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
+/ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
+/ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
+/ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
+/ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
+/ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF \r
+/ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+/============================================================================*/\r
+\r
+#define        STRICT\r
+#include <stdio.h>\r
+#include <stddef.h>\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+#include <mbstring.h>\r
+#include <time.h>\r
+// IPv6対応\r
+//#include <winsock.h>\r
+#include <winsock2.h>\r
+// 切断対策\r
+#include <mstcpip.h>\r
+#include <windowsx.h>\r
+#include <commctrl.h>\r
+\r
+#include "common.h"\r
+#include "resource.h"\r
+\r
+#include <htmlhelp.h>\r
+#include "helpid.h"\r
+\r
+// UTF-8対応\r
+#undef __MBSWRAPPER_H__\r
+#include "mbswrapper.h"\r
+\r
+\r
+/*===== プロトタイプ =====*/\r
+\r
+// 64ビット対応\r
+//static BOOL CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
+static INT_PTR CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
+// 同時接続対応\r
+//static int SendInitCommand(char *Cmd);\r
+static int SendInitCommand(SOCKET Socket, char *Cmd, int *CancelCheckWork);\r
+static void AskUseFireWall(char *Host, int *Fire, int *Pasv, int *List);\r
+static void SaveCurrentSetToHistory(void);\r
+static int ReConnectSkt(SOCKET *Skt);\r
+// 暗号化通信対応\r
+// 同時接続対応\r
+//static SOCKET DoConnect(char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security);\r
+static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork);\r
+static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork);\r
+static int CheckOneTimePassword(char *Pass, char *Reply, int Type);\r
+static BOOL CALLBACK BlkHookFnc(void);\r
+static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port);\r
+// IPv6対応\r
+static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port);\r
+static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork);\r
+// 同時接続対応\r
+//static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet);\r
+static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelCheckWork);\r
+// 同時接続対応\r
+//static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet);\r
+static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet, int *CancelCheckWork);\r
+static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork);\r
+\r
+/*===== 外部参照 =====*/\r
+\r
+extern char FilterStr[FILTER_EXT_LEN+1];\r
+extern char TitleHostName[HOST_ADRS_LEN+1];\r
+extern int CancelFlg;\r
+// タイトルバーにユーザー名表示対応\r
+extern char TitleUserName[USER_NAME_LEN+1];\r
+\r
+/* 設定値 */\r
+extern char UserMailAdrs[USER_MAIL_LEN+1];\r
+extern char FwallHost[HOST_ADRS_LEN+1];\r
+extern char FwallUser[USER_NAME_LEN+1];\r
+extern char FwallPass[PASSWORD_LEN+1];\r
+extern int FwallPort;\r
+extern int FwallType;\r
+extern int FwallDefault;\r
+extern int FwallSecurity;\r
+extern int FwallResolve;\r
+extern int FwallLower;\r
+extern int FwallDelimiter;\r
+extern int PasvDefault;\r
+extern int QuickAnonymous;\r
+// 切断対策\r
+extern int TimeOut;\r
+// UPnP対応\r
+extern int UPnPEnabled;\r
+\r
+/*===== ローカルなワーク =====*/\r
+\r
+static int Anonymous;\r
+static int TryConnect = NO;\r
+static SOCKET CmdCtrlSocket = INVALID_SOCKET;\r
+static SOCKET TrnCtrlSocket = INVALID_SOCKET;\r
+static HOSTDATA CurHost;\r
+\r
+/* 接続中の接続先、SOCKSサーバのアドレス情報を保存しておく */\r
+/* この情報はlistenソケットを取得する際に用いる */\r
+// IPv6対応\r
+//static struct sockaddr_in SocksSockAddr;     /* SOCKSサーバのアドレス情報 */\r
+//static struct sockaddr_in CurSockAddr;               /* 接続先ホストのアドレス情報 */\r
+\r
+static int UseIPadrs;\r
+static char DomainName[HOST_ADRS_LEN+1];\r
+\r
+#if defined(HAVE_TANDEM)\r
+static int Oss = NO;  /* OSS ファイルシステムへアクセスしている場合は YES */\r
+#endif\r
+\r
+\r
+\r
+/*----- ホスト一覧を使ってホストへ接続 ----------------------------------------\r
+*\r
+*      Parameter\r
+*              int Type : ダイアログのタイプ (DLG_TYPE_xxx)\r
+*              int Num : 接続するホスト番号(0~, -1=ダイアログを出す)\r
+\r
+*      Return Value\r
+*              なし\r
+*----------------------------------------------------------------------------*/\r
+\r
+void ConnectProc(int Type, int Num)\r
+{\r
+       int Save;\r
+       int LFSort;\r
+       int LDSort;\r
+       int RFSort;\r
+       int RDSort;\r
+\r
+       SaveBookMark();\r
+       SaveCurrentSetToHost();\r
+\r
+       if((Num >= 0) || (SelectHost(Type) == YES))\r
+       {\r
+               if(Num >= 0)\r
+                       SetCurrentHost(Num);\r
+\r
+               /* 接続中なら切断する */\r
+               if(CmdCtrlSocket != INVALID_SOCKET)\r
+                       DisconnectProc();\r
+\r
+               SetTaskMsg("----------------------------");\r
+\r
+               InitPWDcommand();\r
+               CopyHostFromList(AskCurrentHost(), &CurHost);\r
+               // UTF-8対応\r
+               CurHost.CurNameKanjiCode = CurHost.NameKanjiCode;\r
+               // IPv6対応\r
+               CurHost.CurNetType = CurHost.NetType;\r
+\r
+               if(ConnectRas(CurHost.Dialup, CurHost.DialupAlways, CurHost.DialupNotify, CurHost.DialEntry) == FFFTP_SUCCESS)\r
+               {\r
+                       SetHostKanaCnvImm(CurHost.KanaCnv);\r
+                       SetHostKanjiCodeImm(CurHost.KanjiCode);\r
+                       SetSyncMoveMode(CurHost.SyncMove);\r
+\r
+                       if((AskSaveSortToHost() == YES) && (CurHost.Sort != SORT_NOTSAVED))\r
+                       {\r
+                               DecomposeSortType(CurHost.Sort, &LFSort, &LDSort, &RFSort, &RDSort);\r
+                               SetSortTypeImm(LFSort, LDSort, RFSort, RDSort);\r
+                               ReSortDispList(WIN_LOCAL, &CancelFlg);\r
+                       }\r
+\r
+                       Save = NO;\r
+                       if(strlen(CurHost.PassWord) > 0)\r
+                               Save = YES;\r
+\r
+                       DisableUserOpe();\r
+                       // 暗号化通信対応\r
+                       // 同時接続対応\r
+//                     CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, Save, CurHost.Security);\r
+                       CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, Save, CurHost.Security, &CancelFlg);\r
+                       TrnCtrlSocket = CmdCtrlSocket;\r
+\r
+                       if(CmdCtrlSocket != INVALID_SOCKET)\r
+                       {\r
+                               // 暗号化通信対応\r
+                               switch(CurHost.CryptMode)\r
+                               {\r
+                               case CRYPT_NONE:\r
+                                       if(CurHost.UseFTPIS != NO || CurHost.UseSFTP != NO)\r
+                                       {\r
+                                               if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
+                                                       SetHostEncryption(AskCurrentHost(), CurHost.UseNoEncryption, CurHost.UseFTPES, NO, NO);\r
+                                       }\r
+                                       break;\r
+                               case CRYPT_FTPES:\r
+                                       if(CurHost.UseNoEncryption != NO || CurHost.UseFTPIS != NO || CurHost.UseSFTP != NO)\r
+                                       {\r
+                                               if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
+                                                       SetHostEncryption(AskCurrentHost(), NO, CurHost.UseFTPES, NO, NO);\r
+                                       }\r
+                                       break;\r
+                               case CRYPT_FTPIS:\r
+                                       if(CurHost.UseNoEncryption != NO || CurHost.UseFTPES != NO || CurHost.UseSFTP != NO)\r
+                                       {\r
+                                               if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
+                                                       SetHostEncryption(AskCurrentHost(), NO, NO, CurHost.UseFTPIS, NO);\r
+                                       }\r
+                                       break;\r
+                               case CRYPT_SFTP:\r
+                                       if(CurHost.UseNoEncryption != NO || CurHost.UseFTPES != NO || CurHost.UseFTPIS != NO)\r
+                                       {\r
+                                               if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savecrypt_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
+                                                       SetHostEncryption(AskCurrentHost(), NO, NO, NO, CurHost.UseSFTP);\r
+                                       }\r
+                                       break;\r
+                               }\r
+\r
+                               // UTF-8対応\r
+                               if(CurHost.CurNameKanjiCode == KANJI_AUTO)\r
+                               {\r
+                                       if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
+                                               CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999);\r
+                                       switch(CurHost.CurNameKanjiCode)\r
+                                       {\r
+                                       case KANJI_SJIS:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN345);\r
+                                               break;\r
+                                       case KANJI_JIS:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN346);\r
+                                               break;\r
+                                       case KANJI_EUC:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN347);\r
+                                               break;\r
+                                       case KANJI_UTF8N:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN348);\r
+                                               break;\r
+                                       case KANJI_UTF8HFSX:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN349);\r
+                                               break;\r
+                                       default:\r
+                                               SetTaskMsg(MSGJPN344);\r
+                                               break;\r
+                                       }\r
+                               }\r
+\r
+                               strcpy(TitleHostName, CurHost.HostName);\r
+                               // タイトルバーにユーザー名表示対応\r
+                               strcpy(TitleUserName, CurHost.UserName);\r
+                               DispWindowTitle();\r
+                               SoundPlay(SND_CONNECT);\r
+\r
+                               SendInitCommand(CmdCtrlSocket, CurHost.InitCmd, &CancelFlg);\r
+\r
+                               if(strlen(CurHost.LocalInitDir) > 0)\r
+                               {\r
+                                       DoLocalCWD(CurHost.LocalInitDir);\r
+                                       GetLocalDirForWnd();\r
+                               }\r
+                               InitTransCurDir();\r
+                               DoCWD(CurHost.RemoteInitDir, YES, YES, YES);\r
+\r
+                               LoadBookMark();\r
+                               GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg);\r
+                       }\r
+                       else\r
+                               SoundPlay(SND_ERROR);\r
+\r
+                       EnableUserOpe();\r
+               }\r
+               else\r
+                       SetTaskMsg(MSGJPN001);\r
+       }\r
+       return;\r
+}\r
+\r
+\r
+/*----- ホスト名を入力してホストへ接続 ----------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              なし\r
+*----------------------------------------------------------------------------*/\r
+\r
+void QuickConnectProc(void)\r
+{\r
+       char Tmp[FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1 + 2];\r
+       char File[FMAX_PATH+1];\r
+\r
+       SaveBookMark();\r
+       SaveCurrentSetToHost();\r
+\r
+       if(DialogBoxParam(GetFtpInst(), MAKEINTRESOURCE(hostname_dlg), GetMainHwnd(), QuickConDialogCallBack, (LPARAM)Tmp) == YES)\r
+       {\r
+               /* 接続中なら切断する */\r
+               if(CmdCtrlSocket != INVALID_SOCKET)\r
+                       DisconnectProc();\r
+\r
+               SetTaskMsg("----------------------------");\r
+\r
+               InitPWDcommand();\r
+               CopyDefaultHost(&CurHost);\r
+               // UTF-8対応\r
+               CurHost.CurNameKanjiCode = CurHost.NameKanjiCode;\r
+               // IPv6対応\r
+               CurHost.CurNetType = CurHost.NetType;\r
+               if(SplitUNCpath(Tmp, CurHost.HostAdrs, CurHost.RemoteInitDir, File, CurHost.UserName, CurHost.PassWord, &CurHost.Port) == FFFTP_SUCCESS)\r
+               {\r
+                       if(strlen(CurHost.UserName) == 0)\r
+                       {\r
+                               strcpy(CurHost.UserName, Tmp + FMAX_PATH+1);\r
+                               strcpy(CurHost.PassWord, Tmp + FMAX_PATH+1 + USER_NAME_LEN+1);\r
+                       }\r
+\r
+                       SetCurrentHost(HOSTNUM_NOENTRY);\r
+                       AskUseFireWall(CurHost.HostAdrs, &CurHost.FireWall, &CurHost.Pasv, &CurHost.ListCmdOnly);\r
+                       CurHost.FireWall = (int)Tmp[FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1];\r
+                       CurHost.Pasv = (int)Tmp[FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1 + 1];\r
+\r
+                       SetHostKanaCnvImm(CurHost.KanaCnv);\r
+                       SetHostKanjiCodeImm(CurHost.KanjiCode);\r
+                       SetSyncMoveMode(CurHost.SyncMove);\r
+\r
+                       DisableUserOpe();\r
+                       // 暗号化通信対応\r
+                       // 同時接続対応\r
+//                     CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security);\r
+                       CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg);\r
+                       TrnCtrlSocket = CmdCtrlSocket;\r
+\r
+                       if(CmdCtrlSocket != INVALID_SOCKET)\r
+                       {\r
+                               // UTF-8対応\r
+                               if(CurHost.CurNameKanjiCode == KANJI_AUTO)\r
+                               {\r
+                                       if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
+                                               CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999);\r
+                                       switch(CurHost.CurNameKanjiCode)\r
+                                       {\r
+                                       case KANJI_SJIS:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN345);\r
+                                               break;\r
+                                       case KANJI_JIS:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN346);\r
+                                               break;\r
+                                       case KANJI_EUC:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN347);\r
+                                               break;\r
+                                       case KANJI_UTF8N:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN348);\r
+                                               break;\r
+                                       case KANJI_UTF8HFSX:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN349);\r
+                                               break;\r
+                                       default:\r
+                                               SetTaskMsg(MSGJPN344);\r
+                                               break;\r
+                                       }\r
+                               }\r
+\r
+                               strcpy(TitleHostName, CurHost.HostAdrs);\r
+                               // タイトルバーにユーザー名表示対応\r
+                               strcpy(TitleUserName, CurHost.UserName);\r
+                               DispWindowTitle();\r
+                               SoundPlay(SND_CONNECT);\r
+\r
+                               InitTransCurDir();\r
+                               DoCWD(CurHost.RemoteInitDir, YES, YES, YES);\r
+\r
+                               GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg);\r
+                               EnableUserOpe();\r
+\r
+                               if(strlen(File) > 0)\r
+                                       DirectDownloadProc(File);\r
+                       }\r
+                       else\r
+                       {\r
+                               SoundPlay(SND_ERROR);\r
+                               EnableUserOpe();\r
+                       }\r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+\r
+/*----- クイック接続ダイアログのコールバック ----------------------------------\r
+*\r
+*      Parameter\r
+*              HWND hDlg : ウインドウハンドル\r
+*              UINT message : メッセージ番号\r
+*              WPARAM wParam : メッセージの WPARAM 引数\r
+*              LPARAM lParam : メッセージの LPARAM 引数\r
+*\r
+*      Return Value\r
+*              BOOL TRUE/FALSE\r
+*----------------------------------------------------------------------------*/\r
+\r
+// 64ビット対応\r
+//static BOOL CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
+static INT_PTR CALLBACK QuickConDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
+{\r
+       static char *Buf;\r
+       int i;\r
+       HISTORYDATA Tmp;\r
+\r
+//char Str[HOST_ADRS_LEN+USER_NAME_LEN+INIT_DIR_LEN+5+1];\r
+\r
+       switch (iMessage)\r
+       {\r
+               case WM_INITDIALOG :\r
+                       SendDlgItemMessage(hDlg, QHOST_HOST, CB_LIMITTEXT, FMAX_PATH, 0);\r
+                       SendDlgItemMessage(hDlg, QHOST_HOST, WM_SETTEXT, 0, (LPARAM)"");\r
+                       SendDlgItemMessage(hDlg, QHOST_USER, EM_LIMITTEXT, USER_NAME_LEN, 0);\r
+                       if(QuickAnonymous == YES)\r
+                       {\r
+                               SendDlgItemMessage(hDlg, QHOST_USER, WM_SETTEXT, 0, (LPARAM)"anonymous");\r
+                               SendDlgItemMessage(hDlg, QHOST_PASS, WM_SETTEXT, 0, (LPARAM)UserMailAdrs);\r
+                       }\r
+                       else\r
+                       {\r
+                               SendDlgItemMessage(hDlg, QHOST_USER, WM_SETTEXT, 0, (LPARAM)"");\r
+                               SendDlgItemMessage(hDlg, QHOST_PASS, WM_SETTEXT, 0, (LPARAM)"");\r
+                       }\r
+                       SendDlgItemMessage(hDlg, QHOST_PASS, EM_LIMITTEXT, PASSWORD_LEN, 0);\r
+                       SendDlgItemMessage(hDlg, QHOST_FWALL, BM_SETCHECK, FwallDefault, 0);\r
+                       SendDlgItemMessage(hDlg, QHOST_PASV, BM_SETCHECK, PasvDefault, 0);\r
+                       for(i = 0; i < HISTORY_MAX; i++)\r
+                       {\r
+                               if(GetHistoryByNum(i, &Tmp) == FFFTP_SUCCESS)\r
+                               {\r
+//sprintf(Str, "%s (%s) %s", Tmp.HostAdrs, Tmp.UserName, Tmp.RemoteInitDir);\r
+//SendDlgItemMessage(hDlg, QHOST_HOST, CB_ADDSTRING, 0, (LPARAM)Str);\r
+                                       SendDlgItemMessage(hDlg, QHOST_HOST, CB_ADDSTRING, 0, (LPARAM)Tmp.HostAdrs);\r
+                               }\r
+                       }\r
+                       Buf = (char *)lParam;\r
+                       return(TRUE);\r
+\r
+               case WM_COMMAND :\r
+                       switch(GET_WM_COMMAND_ID(wParam, lParam))\r
+                       {\r
+                               case IDOK :\r
+                                       SendDlgItemMessage(hDlg, QHOST_HOST, WM_GETTEXT, FMAX_PATH+1, (LPARAM)Buf);\r
+                                       SendDlgItemMessage(hDlg, QHOST_USER, WM_GETTEXT, USER_NAME_LEN+1, (LPARAM)Buf + FMAX_PATH+1);\r
+                                       SendDlgItemMessage(hDlg, QHOST_PASS, WM_GETTEXT, PASSWORD_LEN+1, (LPARAM)Buf + FMAX_PATH+1 + USER_NAME_LEN+1);\r
+                                       *(Buf + FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1) = (char)SendDlgItemMessage(hDlg, QHOST_FWALL, BM_GETCHECK, 0, 0);\r
+                                       *(Buf + FMAX_PATH+1 + USER_NAME_LEN+1 + PASSWORD_LEN+1+1) = (char)SendDlgItemMessage(hDlg, QHOST_PASV, BM_GETCHECK, 0, 0);\r
+                                       EndDialog(hDlg, YES);\r
+                                       break;\r
+\r
+                               case IDCANCEL :\r
+                                       EndDialog(hDlg, NO);\r
+                                       break;\r
+\r
+//                             case QHOST_HOST :\r
+//                                     if(HIWORD(wParam) == CBN_EDITCHANGE)\r
+//                                             DoPrintf("EDIT");\r
+//                                     break;\r
+                       }\r
+                       return(TRUE);\r
+       }\r
+       return(FALSE);\r
+}\r
+\r
+\r
+/*----- 指定したホスト名でホストへ接続 ----------------------------------------\r
+*\r
+*      Parameter\r
+*              char *unc : UNC文字列\r
+*              int Kanji : ホストの漢字コード (KANJI_xxx)\r
+*              int Kana : 半角かな→全角変換モード (YES/NO)\r
+*              int Fkanji : ファイル名の漢字コード (KANJI_xxx)\r
+*              int TrMode : 転送モード (TYPE_xx)\r
+*\r
+*      Return Value\r
+*              なし\r
+*----------------------------------------------------------------------------*/\r
+\r
+void DirectConnectProc(char *unc, int Kanji, int Kana, int Fkanji, int TrMode)\r
+{\r
+       char Host[HOST_ADRS_LEN+1];\r
+       char Path[FMAX_PATH+1];\r
+       char File[FMAX_PATH+1];\r
+       char User[USER_NAME_LEN+1];\r
+       char Pass[PASSWORD_LEN+1];\r
+       int Port;\r
+\r
+       SaveBookMark();\r
+       SaveCurrentSetToHost();\r
+\r
+       /* 接続中なら切断する */\r
+       if(CmdCtrlSocket != INVALID_SOCKET)\r
+               DisconnectProc();\r
+\r
+       SetTaskMsg("----------------------------");\r
+\r
+       InitPWDcommand();\r
+       if(SplitUNCpath(unc, Host, Path, File, User, Pass, &Port) == FFFTP_SUCCESS)\r
+       {\r
+               if(strlen(User) == 0)\r
+               {\r
+                       strcpy(User, "anonymous");\r
+                       strcpy(Pass, UserMailAdrs);\r
+               }\r
+\r
+               CopyDefaultHost(&CurHost);\r
+\r
+               SetCurrentHost(HOSTNUM_NOENTRY);\r
+               strcpy(CurHost.HostAdrs, Host);\r
+               strcpy(CurHost.UserName, User);\r
+               strcpy(CurHost.PassWord, Pass);\r
+               strcpy(CurHost.RemoteInitDir, Path);\r
+               AskUseFireWall(CurHost.HostAdrs, &CurHost.FireWall, &CurHost.Pasv, &CurHost.ListCmdOnly);\r
+               CurHost.Port = Port;\r
+               CurHost.KanjiCode = Kanji;\r
+               CurHost.KanaCnv = Kana;\r
+               CurHost.NameKanjiCode = Fkanji;\r
+               CurHost.KanaCnv = YES;                  /* とりあえず */\r
+               // UTF-8対応\r
+               CurHost.CurNameKanjiCode = CurHost.NameKanjiCode;\r
+               // IPv6対応\r
+               CurHost.CurNetType = CurHost.NetType;\r
+\r
+               SetHostKanaCnvImm(CurHost.KanaCnv);\r
+               SetHostKanjiCodeImm(CurHost.KanjiCode);\r
+               SetSyncMoveMode(CurHost.SyncMove);\r
+\r
+               if(TrMode != TYPE_DEFAULT)\r
+               {\r
+                       SetTransferTypeImm(TrMode);\r
+                       DispTransferType();\r
+               }\r
+\r
+               DisableUserOpe();\r
+               // 暗号化通信対応\r
+               // 同時接続対応\r
+//             CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security);\r
+               CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg);\r
+               TrnCtrlSocket = CmdCtrlSocket;\r
+\r
+               if(CmdCtrlSocket != INVALID_SOCKET)\r
+               {\r
+                       // UTF-8対応\r
+                       if(CurHost.CurNameKanjiCode == KANJI_AUTO)\r
+                       {\r
+                               if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
+                                       CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999);\r
+                               switch(CurHost.CurNameKanjiCode)\r
+                               {\r
+                               case KANJI_SJIS:\r
+                                       SetTaskMsg(MSGJPN343, MSGJPN345);\r
+                                       break;\r
+                               case KANJI_JIS:\r
+                                       SetTaskMsg(MSGJPN343, MSGJPN346);\r
+                                       break;\r
+                               case KANJI_EUC:\r
+                                       SetTaskMsg(MSGJPN343, MSGJPN347);\r
+                                       break;\r
+                               case KANJI_UTF8N:\r
+                                       SetTaskMsg(MSGJPN343, MSGJPN348);\r
+                                       break;\r
+                               case KANJI_UTF8HFSX:\r
+                                       SetTaskMsg(MSGJPN343, MSGJPN349);\r
+                                       break;\r
+                               default:\r
+                                       SetTaskMsg(MSGJPN344);\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+                       strcpy(TitleHostName, CurHost.HostAdrs);\r
+                       // タイトルバーにユーザー名表示対応\r
+                       strcpy(TitleUserName, CurHost.UserName);\r
+                       DispWindowTitle();\r
+                       SoundPlay(SND_CONNECT);\r
+\r
+                       InitTransCurDir();\r
+                       DoCWD(CurHost.RemoteInitDir, YES, YES, YES);\r
+\r
+                       GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg);\r
+                       EnableUserOpe();\r
+\r
+                       if(strlen(File) > 0)\r
+                               DirectDownloadProc(File);\r
+                       else\r
+                               ResetAutoExitFlg();\r
+               }\r
+               else\r
+               {\r
+                       SoundPlay(SND_ERROR);\r
+                       EnableUserOpe();\r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+\r
+/*----- ホストのヒストリで指定されたホストへ接続 ------------------------------\r
+*\r
+*      Parameter\r
+*              int MenuCmd : 取り出すヒストリに割り当てられたメニューコマンド\r
+*\r
+*      Return Value\r
+*              なし\r
+*----------------------------------------------------------------------------*/\r
+\r
+void HistoryConnectProc(int MenuCmd)\r
+{\r
+       HISTORYDATA Hist;\r
+       int LFSort;\r
+       int LDSort;\r
+       int RFSort;\r
+       int RDSort;\r
+\r
+       if(GetHistoryByCmd(MenuCmd, &Hist) == FFFTP_SUCCESS)\r
+       {\r
+               SaveBookMark();\r
+               SaveCurrentSetToHost();\r
+\r
+               /* 接続中なら切断する */\r
+               if(CmdCtrlSocket != INVALID_SOCKET)\r
+                       DisconnectProc();\r
+\r
+               SetTaskMsg("----------------------------");\r
+\r
+               InitPWDcommand();\r
+               CopyHistoryToHost(&Hist, &CurHost);\r
+               // UTF-8対応\r
+               CurHost.CurNameKanjiCode = CurHost.NameKanjiCode;\r
+               // IPv6対応\r
+               CurHost.CurNetType = CurHost.NetType;\r
+\r
+               if(ConnectRas(CurHost.Dialup, CurHost.DialupAlways, CurHost.DialupNotify, CurHost.DialEntry) == FFFTP_SUCCESS)\r
+               {\r
+                       SetCurrentHost(HOSTNUM_NOENTRY);\r
+                       SetHostKanaCnvImm(CurHost.KanaCnv);\r
+                       SetHostKanjiCodeImm(CurHost.KanjiCode);\r
+                       SetSyncMoveMode(CurHost.SyncMove);\r
+\r
+                       DecomposeSortType(CurHost.Sort, &LFSort, &LDSort, &RFSort, &RDSort);\r
+                       SetSortTypeImm(LFSort, LDSort, RFSort, RDSort);\r
+                       ReSortDispList(WIN_LOCAL, &CancelFlg);\r
+\r
+                       SetTransferTypeImm(Hist.Type);\r
+                       DispTransferType();\r
+\r
+                       DisableUserOpe();\r
+                       // 暗号化通信対応\r
+                       // 同時接続対応\r
+//                     CmdCtrlSocket = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security);\r
+                       CmdCtrlSocket = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg);\r
+                       TrnCtrlSocket = CmdCtrlSocket;\r
+\r
+                       if(CmdCtrlSocket != INVALID_SOCKET)\r
+                       {\r
+                               // UTF-8対応\r
+                               if(CurHost.CurNameKanjiCode == KANJI_AUTO)\r
+                               {\r
+                                       if(DoDirListCmdSkt("", "", 999, &CancelFlg) == FTP_COMPLETE)\r
+                                               CurHost.CurNameKanjiCode = AnalyzeNameKanjiCode(999);\r
+                                       switch(CurHost.CurNameKanjiCode)\r
+                                       {\r
+                                       case KANJI_SJIS:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN345);\r
+                                               break;\r
+                                       case KANJI_JIS:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN346);\r
+                                               break;\r
+                                       case KANJI_EUC:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN347);\r
+                                               break;\r
+                                       case KANJI_UTF8N:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN348);\r
+                                               break;\r
+                                       case KANJI_UTF8HFSX:\r
+                                               SetTaskMsg(MSGJPN343, MSGJPN349);\r
+                                               break;\r
+                                       default:\r
+                                               SetTaskMsg(MSGJPN344);\r
+                                               break;\r
+                                       }\r
+                               }\r
+\r
+                               strcpy(TitleHostName, CurHost.HostAdrs);\r
+                               // タイトルバーにユーザー名表示対応\r
+                               strcpy(TitleUserName, CurHost.UserName);\r
+                               DispWindowTitle();\r
+                               SoundPlay(SND_CONNECT);\r
+\r
+                               SendInitCommand(CmdCtrlSocket, CurHost.InitCmd, &CancelFlg);\r
+\r
+                               DoLocalCWD(CurHost.LocalInitDir);\r
+                               GetLocalDirForWnd();\r
+\r
+                               InitTransCurDir();\r
+                               DoCWD(CurHost.RemoteInitDir, YES, YES, YES);\r
+\r
+                               GetRemoteDirForWnd(CACHE_NORMAL, &CancelFlg);\r
+                       }\r
+                       else\r
+                               SoundPlay(SND_ERROR);\r
+\r
+                       EnableUserOpe();\r
+               }\r
+               else\r
+                       SetTaskMsg(MSGJPN002);\r
+       }\r
+       else\r
+               SoundPlay(SND_ERROR);\r
+\r
+       return;\r
+}\r
+\r
+\r
+/*----- ホストの初期化コマンドを送る ------------------------------------------\r
+*\r
+*      Parameter\r
+*              int Cmd : 初期化コマンドス\r
+*\r
+*      Return Value\r
+*              なし\r
+*\r
+*      NOte\r
+*              初期化コマンドは以下のようなフォーマットであること\r
+*                      cmd1\0\r
+*                      cmd1\r\ncmd2\r\n\0\r
+*----------------------------------------------------------------------------*/\r
+\r
+// 同時接続対応\r
+//static int SendInitCommand(char *Cmd)\r
+static int SendInitCommand(SOCKET Socket, char *Cmd, int *CancelCheckWork)\r
+{\r
+       char Tmp[INITCMD_LEN+1];\r
+       char *Pos;\r
+\r
+       while(strlen(Cmd) > 0)\r
+       {\r
+               strcpy(Tmp, Cmd);\r
+               if((Pos = strchr(Tmp, '\r')) != NULL)\r
+                       *Pos = NUL;\r
+               if(strlen(Tmp) > 0)\r
+//                     DoQUOTE(Tmp);\r
+                       DoQUOTE(Socket, Tmp, CancelCheckWork);\r
+\r
+               if((Cmd = strchr(Cmd, '\n')) != NULL)\r
+                       Cmd++;\r
+               else\r
+                       break;\r
+       }\r
+       return(0);\r
+}\r
+\r
+\r
+/*----- 指定のホストはFireWallを使う設定かどうかを返す ------------------------\r
+*\r
+*      Parameter\r
+*              char *Hots : ホスト名\r
+*              int *Fire : FireWallを使うかどうかを返すワーク\r
+*              int *Pasv : PASVモードを返すワーク\r
+*              int *List : LISTコマンドのみ使用フラグ\r
+*\r
+*      Return Value\r
+*              なし\r
+*----------------------------------------------------------------------------*/\r
+\r
+static void AskUseFireWall(char *Host, int *Fire, int *Pasv, int *List)\r
+{\r
+       int i;\r
+       HOSTDATA Tmp;\r
+\r
+       *Fire = FwallDefault;\r
+       *Pasv = PasvDefault;\r
+       // NLSTを送ってしまうバグ修正(ただしNLSTを使うべきホストへクイック接続できなくなる)\r
+//     *List = NO;\r
+\r
+       i = 0;\r
+       while(CopyHostFromList(i, &Tmp) == FFFTP_SUCCESS)\r
+       {\r
+               if(strcmp(Host, Tmp.HostAdrs) == 0)\r
+               {\r
+                       *Fire = Tmp.FireWall;\r
+                       *Pasv = Tmp.Pasv;\r
+                       *List = Tmp.ListCmdOnly;\r
+                       break;\r
+               }\r
+               i++;\r
+       }\r
+       return;\r
+}\r
+\r
+\r
+/*----- 接続しているホストのアドレスを返す ------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              char *ホストのアドレス\r
+*----------------------------------------------------------------------------*/\r
+\r
+char *AskHostAdrs(void)\r
+{\r
+       return(CurHost.HostAdrs);\r
+}\r
+\r
+\r
+/*----- 接続しているホストのポートを返す --------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int ホストのポート\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskHostPort(void)\r
+{\r
+       return(CurHost.Port);\r
+}\r
+\r
+/*----- 接続しているホストのファイル名の漢字コードを返す ----------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int 漢字コード (KANJI_xxx)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskHostNameKanji(void)\r
+{\r
+       // UTF-8対応\r
+//     if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+//             CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+//\r
+//     return(CurHost.NameKanjiCode);\r
+       return(CurHost.CurNameKanjiCode);\r
+}\r
+\r
+\r
+/*----- 接続しているホストのファイル名の半角カナ変換フラグを返す --------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int 半角カナを全角に変換するかどうか (YES/NO)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskHostNameKana(void)\r
+{\r
+       // 同時接続対応\r
+       HOSTDATA TmpHost;\r
+       TmpHost = CurHost;\r
+\r
+       if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+               // 同時接続対応\r
+//             CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+               CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
+\r
+       // 同時接続対応\r
+//     return(CurHost.NameKanaCnv);\r
+       return(TmpHost.NameKanaCnv);\r
+}\r
+\r
+\r
+/*----- 接続しているホストのLISTコマンドモードを返す --------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int LISTコマンドモード (YES/NO)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskListCmdMode(void)\r
+{\r
+       // 同時接続対応\r
+       HOSTDATA TmpHost;\r
+       TmpHost = CurHost;\r
+\r
+       if(CurHost.HostType == HTYPE_VMS)\r
+               return(YES);\r
+       else\r
+       {\r
+               if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+                       // 同時接続対応\r
+//                     CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+                       CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
+               // 同時接続対応\r
+//             return(CurHost.ListCmdOnly);\r
+               return(TmpHost.ListCmdOnly);\r
+       }\r
+}\r
+\r
+\r
+/*----- 接続しているホストでNLST -Rを使うかどうかを返す ------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int NLST -Rを使うかどうか (YES/NO)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskUseNLST_R(void)\r
+{\r
+       // 同時接続対応\r
+       HOSTDATA TmpHost;\r
+       TmpHost = CurHost;\r
+\r
+       if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+               // 同時接続対応\r
+//             CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+               CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
+\r
+       // 同時接続対応\r
+//     return(CurHost.UseNLST_R);\r
+       return(TmpHost.UseNLST_R);\r
+}\r
+\r
+\r
+/*----- 接続しているホストのChmodコマンドを返す -------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              char *Chmodコマンド\r
+*----------------------------------------------------------------------------*/\r
+\r
+char *AskHostChmodCmd(void)\r
+{\r
+       // 同時接続対応\r
+       HOSTDATA TmpHost;\r
+       TmpHost = CurHost;\r
+\r
+       if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+               // 同時接続対応\r
+//             CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+               CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
+\r
+       // 同時接続対応\r
+//     return(CurHost.ChmodCmd);\r
+       return(TmpHost.ChmodCmd);\r
+}\r
+\r
+\r
+/*----- 接続しているホストのタイムゾーンを返す --------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int タイムゾーン\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskHostTimeZone(void)\r
+{\r
+       // 同時接続対応\r
+       HOSTDATA TmpHost;\r
+       TmpHost = CurHost;\r
+\r
+       if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+               // 同時接続対応\r
+//             CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+               CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
+\r
+       // 同時接続対応\r
+//     return(CurHost.TimeZone);\r
+       return(TmpHost.TimeZone);\r
+}\r
+\r
+\r
+/*----- 接続しているホストのPASVモードを返す ----------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int PASVモードかどうか (YES/NO)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskPasvMode(void)\r
+{\r
+       return(CurHost.Pasv);\r
+}\r
+\r
+\r
+/*----- 接続しているホストのLNSTファイル名を返す ------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              char *ファイル名/オプション\r
+*----------------------------------------------------------------------------*/\r
+\r
+char *AskHostLsName(void)\r
+{\r
+       // 同時接続対応\r
+       HOSTDATA TmpHost;\r
+       TmpHost = CurHost;\r
+\r
+       if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+               // 同時接続対応\r
+//             CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+               CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
+\r
+       // 同時接続対応\r
+//     return(CurHost.LsName);\r
+       return(TmpHost.LsName);\r
+}\r
+\r
+\r
+/*----- 接続しているホストのホストタイプを返す --------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              char *ファイル名/オプション\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskHostType(void)\r
+{\r
+       // 同時接続対応\r
+       HOSTDATA TmpHost;\r
+       TmpHost = CurHost;\r
+\r
+       if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+               // 同時接続対応\r
+//             CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+               CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
+\r
+#if defined(HAVE_TANDEM)\r
+       /* OSS ファイルシステムは UNIX ファイルシステムと同じでいいので AUTO を返す\r
+          ただし、Guardian ファイルシステムに戻ったときにおかしくならないように\r
+          CurHost.HostType 変数は更新しない */\r
+       if(CurHost.HostType == HTYPE_TANDEM && Oss == YES)\r
+               return(HTYPE_AUTO);\r
+#endif\r
+\r
+       // 同時接続対応\r
+//     return(CurHost.HostType);\r
+       return(TmpHost.HostType);\r
+}\r
+\r
+\r
+/*----- 接続しているホストはFireWallを使うホストかどうかを返す ----------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int FireWallを使うかどうか (YES/NO)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskHostFireWall(void)\r
+{\r
+       return(CurHost.FireWall);\r
+}\r
+\r
+\r
+/*----- 接続しているホストでフルパスでファイルアクセスしないかどうかを返す ----\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int フルパスでアクセスしない (YES=フルパス禁止/NO)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskNoFullPathMode(void)\r
+{\r
+       if(CurHost.HostType == HTYPE_VMS)\r
+               return(YES);\r
+       else\r
+               return(CurHost.NoFullPath);\r
+}\r
+\r
+\r
+/*----- 接続しているユーザ名を返す --------------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              char *ユーザ名\r
+*----------------------------------------------------------------------------*/\r
+\r
+char *AskHostUserName(void)\r
+{\r
+       return(CurHost.UserName);\r
+}\r
+\r
+\r
+/*----- 現在の設定をホストの設定にセットする ----------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              なし\r
+*\r
+*      Note\r
+*              カレントディレクトリ、ソート方法をホストの設定にセットする\r
+*----------------------------------------------------------------------------*/\r
+\r
+void SaveCurrentSetToHost(void)\r
+{\r
+       int Host;\r
+       char LocDir[FMAX_PATH+1];\r
+       char HostDir[FMAX_PATH+1];\r
+       // 同時接続対応\r
+       HOSTDATA TmpHost;\r
+       TmpHost = CurHost;\r
+\r
+       if(TrnCtrlSocket != INVALID_SOCKET)\r
+       {\r
+               if((Host = AskCurrentHost()) != HOSTNUM_NOENTRY)\r
+               {\r
+                       // 同時接続対応\r
+//                     CopyHostFromListInConnect(Host, &CurHost);\r
+//                     if(CurHost.LastDir == YES)\r
+                       CopyHostFromListInConnect(Host, &TmpHost);\r
+                       if(TmpHost.LastDir == YES)\r
+                       {\r
+                               AskLocalCurDir(LocDir, FMAX_PATH);\r
+                               AskRemoteCurDir(HostDir, FMAX_PATH);\r
+                               SetHostDir(AskCurrentHost(), LocDir, HostDir);\r
+                       }\r
+                       SetHostSort(AskCurrentHost(), AskSortType(ITEM_LFILE), AskSortType(ITEM_LDIR), AskSortType(ITEM_RFILE), AskSortType(ITEM_RDIR));\r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+\r
+/*----- 現在の設定をヒストリにセットする --------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              なし\r
+*----------------------------------------------------------------------------*/\r
+\r
+static void SaveCurrentSetToHistory(void)\r
+{\r
+       char LocDir[FMAX_PATH+1];\r
+       char HostDir[FMAX_PATH+1];\r
+\r
+       AskLocalCurDir(LocDir, FMAX_PATH);\r
+       AskRemoteCurDir(HostDir, FMAX_PATH);\r
+       strcpy(CurHost.LocalInitDir, LocDir);\r
+       strcpy(CurHost.RemoteInitDir, HostDir);\r
+\r
+       CurHost.Sort = AskSortType(ITEM_LFILE) * 0x1000000 | AskSortType(ITEM_LDIR) * 0x10000 | AskSortType(ITEM_RFILE) * 0x100 | AskSortType(ITEM_RDIR);\r
+\r
+       CurHost.KanjiCode = AskHostKanjiCode();\r
+       CurHost.KanaCnv = AskHostKanaCnv();\r
+\r
+       CurHost.SyncMove = AskSyncMoveMode();\r
+\r
+       AddHostToHistory(&CurHost, AskTransferType());\r
+       SetAllHistoryToMenu();\r
+\r
+       return;\r
+}\r
+\r
+\r
+/*----- コマンドコントロールソケットの再接続 ----------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int ステータス\r
+*                      FFFTP_SUCCESS/FFFTP_FAIL\r
+*----------------------------------------------------------------------------*/\r
+\r
+int ReConnectCmdSkt(void)\r
+{\r
+       int Sts;\r
+\r
+\r
+       // 同時接続対応\r
+//     if(CmdCtrlSocket != TrnCtrlSocket)\r
+//             do_closesocket(TrnCtrlSocket);\r
+//     TrnCtrlSocket = INVALID_SOCKET;\r
+\r
+       // 同時接続対応\r
+//     Sts = ReConnectSkt(&CmdCtrlSocket);\r
+       if(AskShareProh() == YES && AskTransferNow() == YES)\r
+               SktShareProh();\r
+       else\r
+       {\r
+               if(CmdCtrlSocket == TrnCtrlSocket)\r
+                       TrnCtrlSocket = INVALID_SOCKET;\r
+               Sts = ReConnectSkt(&CmdCtrlSocket);\r
+       }\r
+\r
+       // 同時接続対応\r
+//     TrnCtrlSocket = CmdCtrlSocket;\r
+       if(TrnCtrlSocket == INVALID_SOCKET)\r
+               TrnCtrlSocket = CmdCtrlSocket;\r
+\r
+       return(Sts);\r
+}\r
+\r
+\r
+/*----- 転送コントロールソケットの再接続 --------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int ステータス\r
+*                      FFFTP_SUCCESS/FFFTP_FAIL\r
+*----------------------------------------------------------------------------*/\r
+\r
+//int ReConnectTrnSkt(void)\r
+//{\r
+//     return(ReConnectSkt(&TrnCtrlSocket));\r
+//}\r
+// 同時接続対応\r
+int ReConnectTrnSkt(SOCKET *Skt, int *CancelCheckWork)\r
+{\r
+//     char Path[FMAX_PATH+1];\r
+       int Sts;\r
+       // 暗号化通信対応\r
+       HOSTDATA HostData;\r
+\r
+       Sts = FFFTP_FAIL;\r
+\r
+       SetTaskMsg(MSGJPN003);\r
+\r
+//     DisableUserOpe();\r
+       /* 現在のソケットは切断 */\r
+       if(*Skt != INVALID_SOCKET)\r
+               do_closesocket(*Skt);\r
+       /* 再接続 */\r
+       // 暗号化通信対応\r
+       HostData = CurHost;\r
+       if(HostData.CryptMode != CRYPT_NONE)\r
+               HostData.UseNoEncryption = NO;\r
+       if(HostData.CryptMode != CRYPT_FTPES)\r
+               HostData.UseFTPES = NO;\r
+       if(HostData.CryptMode != CRYPT_FTPIS)\r
+               HostData.UseFTPIS = NO;\r
+       if(HostData.CryptMode != CRYPT_SFTP)\r
+               HostData.UseSFTP = NO;\r
+       // UTF-8対応\r
+       HostData.CurNameKanjiCode = HostData.NameKanjiCode;\r
+       // IPv6対応\r
+       HostData.CurNetType = HostData.NetType;\r
+       // 同時接続対応\r
+       HostData.NoDisplayUI = YES;\r
+       // 暗号化通信対応\r
+       // 同時接続対応\r
+//     if((*Skt = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET)\r
+       if((*Skt = DoConnect(&HostData, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, CancelCheckWork)) != INVALID_SOCKET)\r
+       {\r
+               SendInitCommand(*Skt, CurHost.InitCmd, CancelCheckWork);\r
+//             AskRemoteCurDir(Path, FMAX_PATH);\r
+//             DoCWD(Path, YES, YES, YES);\r
+               Sts = FFFTP_SUCCESS;\r
+       }\r
+       else\r
+               SoundPlay(SND_ERROR);\r
+\r
+//     EnableUserOpe();\r
+       return(Sts);\r
+}\r
+\r
+\r
+/*----- 回線の再接続 ----------------------------------------------------------\r
+*\r
+*      Parameter\r
+*              SOCKET *Skt : 接続したソケットを返すワーク\r
+*\r
+*      Return Value\r
+*              int ステータス\r
+*                      FFFTP_SUCCESS/FFFTP_FAIL\r
+*----------------------------------------------------------------------------*/\r
+\r
+static int ReConnectSkt(SOCKET *Skt)\r
+{\r
+       char Path[FMAX_PATH+1];\r
+       int Sts;\r
+\r
+       Sts = FFFTP_FAIL;\r
+\r
+       SetTaskMsg(MSGJPN003);\r
+\r
+       DisableUserOpe();\r
+       /* 現在のソケットは切断 */\r
+       if(*Skt != INVALID_SOCKET)\r
+               do_closesocket(*Skt);\r
+       /* 再接続 */\r
+       // 暗号化通信対応\r
+       // 同時接続対応\r
+//     if((*Skt = DoConnect(CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security)) != INVALID_SOCKET)\r
+       if((*Skt = DoConnect(&CurHost, CurHost.HostAdrs, CurHost.UserName, CurHost.PassWord, CurHost.Account, CurHost.Port, CurHost.FireWall, NO, CurHost.Security, &CancelFlg)) != INVALID_SOCKET)\r
+       {\r
+               SendInitCommand(*Skt, CurHost.InitCmd, &CancelFlg);\r
+               AskRemoteCurDir(Path, FMAX_PATH);\r
+               DoCWD(Path, YES, YES, YES);\r
+               Sts = FFFTP_SUCCESS;\r
+       }\r
+       else\r
+               SoundPlay(SND_ERROR);\r
+\r
+       EnableUserOpe();\r
+       return(Sts);\r
+}\r
+\r
+\r
+/*----- コマンドコントロールソケットを返す ------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              SOCKET コマンドコントロールソケット\r
+*----------------------------------------------------------------------------*/\r
+\r
+SOCKET AskCmdCtrlSkt(void)\r
+{\r
+       return(CmdCtrlSocket);\r
+}\r
+\r
+\r
+/*----- 転送コントロールソケットを返す ----------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              SOCKET 転送コントロールソケット\r
+*----------------------------------------------------------------------------*/\r
+\r
+SOCKET AskTrnCtrlSkt(void)\r
+{\r
+       return(TrnCtrlSocket);\r
+}\r
+\r
+\r
+/*----- コマンド/転送コントロールソケットの共有を解除 ------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              なし\r
+*----------------------------------------------------------------------------*/\r
+\r
+void SktShareProh(void)\r
+{\r
+       if(CmdCtrlSocket == TrnCtrlSocket)\r
+       {\r
+\r
+//SetTaskMsg("############### SktShareProh");\r
+\r
+               // 同時接続対応\r
+//             CmdCtrlSocket = INVALID_SOCKET;\r
+//             ReConnectSkt(&CmdCtrlSocket);\r
+               if(CurHost.ReuseCmdSkt == YES)\r
+               {\r
+                       CurHost.ReuseCmdSkt = NO;\r
+                       CmdCtrlSocket = INVALID_SOCKET;\r
+                       ReConnectSkt(&CmdCtrlSocket);\r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+\r
+/*----- コマンド/転送コントロールソケットの共有が解除されているかチェック ----\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int ステータス\r
+*                      YES=共有解除/NO=共有\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskShareProh(void)\r
+{\r
+       int Sts;\r
+\r
+       Sts = YES;\r
+       // 同時接続対応\r
+//     if(CmdCtrlSocket == TrnCtrlSocket)\r
+       if(CmdCtrlSocket == TrnCtrlSocket || TrnCtrlSocket == INVALID_SOCKET)\r
+               Sts = NO;\r
+\r
+       return(Sts);\r
+}\r
+\r
+\r
+/*----- ホストから切断 --------------------------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              なし\r
+*----------------------------------------------------------------------------*/\r
+\r
+void DisconnectProc(void)\r
+{\r
+\r
+//SetTaskMsg("############### Disconnect Cmd=%x, Trn=%x", CmdCtrlSocket,TrnCtrlSocket);\r
+\r
+       // 同時接続対応\r
+       AbortAllTransfer();\r
+\r
+       if((CmdCtrlSocket != INVALID_SOCKET) && (CmdCtrlSocket != TrnCtrlSocket))\r
+       {\r
+               // 同時接続対応\r
+//             DoQUIT(CmdCtrlSocket);\r
+               DoQUIT(CmdCtrlSocket, &CancelFlg);\r
+               DoClose(CmdCtrlSocket);\r
+       }\r
+\r
+       if(TrnCtrlSocket != INVALID_SOCKET)\r
+       {\r
+               // 同時接続対応\r
+//             DoQUIT(TrnCtrlSocket);\r
+               DoQUIT(TrnCtrlSocket, &CancelFlg);\r
+               DoClose(TrnCtrlSocket);\r
+\r
+               SaveCurrentSetToHistory();\r
+\r
+               EraseRemoteDirForWnd();\r
+               SetTaskMsg(MSGJPN004);\r
+       }\r
+\r
+       TrnCtrlSocket = INVALID_SOCKET;\r
+       CmdCtrlSocket = INVALID_SOCKET;\r
+\r
+       DispWindowTitle();\r
+       MakeButtonsFocus();\r
+       ClearBookMark();\r
+\r
+       return;\r
+}\r
+\r
+\r
+/*----- ソケットが強制切断されたときの処理 ------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              なし\r
+*----------------------------------------------------------------------------*/\r
+\r
+void DisconnectSet(void)\r
+{\r
+       CmdCtrlSocket = INVALID_SOCKET;\r
+       TrnCtrlSocket = INVALID_SOCKET;\r
+\r
+       EraseRemoteDirForWnd();\r
+       DispWindowTitle();\r
+       MakeButtonsFocus();\r
+       SetTaskMsg(MSGJPN005);\r
+       return;\r
+}\r
+\r
+\r
+/*----- ホストに接続中かどうかを返す ------------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int ステータス (YES/NO)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskConnecting(void)\r
+{\r
+       int Sts;\r
+\r
+       Sts = NO;\r
+       if(TrnCtrlSocket != INVALID_SOCKET)\r
+               Sts = YES;\r
+\r
+       return(Sts);\r
+}\r
+\r
+\r
+#if defined(HAVE_TANDEM)\r
+/*----- 接続している本当のホストのホストタイプを返す --------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              char *ファイル名/オプション\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskRealHostType(void)\r
+{\r
+       // 同時接続対応\r
+       HOSTDATA TmpHost;\r
+       TmpHost = CurHost;\r
+\r
+       if(AskCurrentHost() != HOSTNUM_NOENTRY)\r
+               // 同時接続対応\r
+//             CopyHostFromListInConnect(AskCurrentHost(), &CurHost);\r
+               CopyHostFromListInConnect(AskCurrentHost(), &TmpHost);\r
+\r
+       // 同時接続対応\r
+//     return(CurHost.HostType);\r
+       return(TmpHost.HostType);\r
+}\r
+\r
+/*----- OSS ファイルシステムにアクセスしているかどうかのフラグを変更する ------\r
+*\r
+*      Parameter\r
+*              int ステータス (YES/NO)\r
+*\r
+*      Return Value\r
+*              int ステータス (YES/NO)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int SetOSS(int wkOss)\r
+{\r
+       if(Oss != wkOss) {\r
+               if (wkOss == YES) {\r
+                       strcpy(CurHost.InitCmd, "OSS");\r
+               } else {\r
+                       strcpy(CurHost.InitCmd, "GUARDIAN");\r
+               }\r
+       }\r
+       Oss = wkOss;\r
+       return(Oss);\r
+}\r
+\r
+/*----- OSS ファイルシステムにアクセスしているかどうかを返す ------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int ステータス (YES/NO)\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskOSS(void)\r
+{\r
+       return(Oss);\r
+}\r
+#endif /* HAVE_TANDEM */\r
+\r
+\r
+/*----- ホストへ接続する ------------------------------------------------------\r
+*\r
+*      Parameter\r
+*              char *Host : ホスト名\r
+*              char *User : ユーザ名\r
+*              char *Pass : パスワード\r
+*              char *Acct : アカウント\r
+*              int Port : ポート\r
+*              int Fwall : FireWallを使うかどうか (YES/NO)\r
+*              int SavePass : パスワードを再入力した時に保存するかどうか (YES/NO)\r
+*              int Security : セキュリティ (SECURITY_xxx, MDx)\r
+*\r
+*      Return Value\r
+*              SOCKET ソケット\r
+*\r
+*      Note\r
+*              ホスト名、ユーザ名、パスワードが指定されていなかったときは、接続に使用\r
+*              したものをコピーしてかえす\r
+*                      char *Host : ホスト名\r
+*                      char *User : ユーザ名\r
+*                      char *Pass : パスワード\r
+*                      char *Acct : アカウント\r
+*\r
+*              FireWallは次のように動作する\r
+*                      TYPE1   Connect fire → USER user(f) → PASS pass(f) → SITE host → USER user(h) →      PASS pass(h) → ACCT acct\r
+*                      TYPE2   Connect fire → USER user(f) → PASS pass(f) →              USER user(h)@host → PASS pass(h) → ACCT acct\r
+*                      TYPE3   Connect fire →                                              USER user(h)@host → PASS pass(h) → ACCT acct\r
+*                      TYPE4   Connect fire →                                 OPEN host → USER user(h) →      PASS pass(h) → ACCT acct\r
+*                      TYPE5   SOCKS4\r
+*                      none    Connect host →                                              USER user(h) →      PASS pass(h) → ACCT acct\r
+*----------------------------------------------------------------------------*/\r
+\r
+// 暗号化通信対応\r
+static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork)\r
+{\r
+       int Sts;\r
+       int Flg;\r
+       int Anony;\r
+       SOCKET ContSock;\r
+       char Buf[1024];\r
+       char Reply[1024];\r
+       int Continue;\r
+       int ReInPass;\r
+       char *Tmp;\r
+       int HostPort;\r
+       static const char *SiteTbl[4] = { "SITE", "site", "OPEN", "open" };\r
+       char TmpBuf[ONELINE_BUF_SIZE];\r
+       struct linger LingerOpt;\r
+       struct tcp_keepalive KeepAlive;\r
+       DWORD dwTmp;\r
+\r
+       // 暗号化通信対応\r
+       ContSock = INVALID_SOCKET;\r
+\r
+       if(CryptMode == CRYPT_NONE || CryptMode == CRYPT_FTPES || CryptMode == CRYPT_FTPIS)\r
+       {\r
+               if(Fwall == YES)\r
+                       Fwall = FwallType;\r
+               else\r
+                       Fwall = FWALL_NONE;\r
+\r
+               TryConnect = YES;\r
+               // 暗号化通信対応\r
+//             CancelFlg = NO;\r
+#if 0\r
+//             WSASetBlockingHook(BlkHookFnc);\r
+#endif\r
+\r
+               ContSock = INVALID_SOCKET;\r
+\r
+               HostPort = Port;\r
+               Tmp = Host;\r
+               if(((Fwall >= FWALL_FU_FP_SITE) && (Fwall <= FWALL_OPEN)) ||\r
+                  (Fwall == FWALL_SIDEWINDER) ||\r
+                  (Fwall == FWALL_FU_FP))\r
+               {\r
+                       Tmp = FwallHost;\r
+                       Port = FwallPort;\r
+               }\r
+\r
+               if(strlen(Tmp) != 0)\r
+               {\r
+                       // 同時接続対応\r
+//                     if((ContSock = connectsock(Tmp, Port, "", &CancelFlg)) != INVALID_SOCKET)\r
+                       if((ContSock = connectsock(Tmp, Port, "", CancelCheckWork)) != INVALID_SOCKET)\r
+                       {\r
+                               // バッファを無効\r
+#ifdef DISABLE_CONTROL_NETWORK_BUFFERS\r
+                               int BufferSize = 0;\r
+                               setsockopt(ContSock, SOL_SOCKET, SO_SNDBUF, (char*)&BufferSize, sizeof(int));\r
+                               setsockopt(ContSock, SOL_SOCKET, SO_RCVBUF, (char*)&BufferSize, sizeof(int));\r
+#endif\r
+                               // FTPIS対応\r
+//                             while((Sts = ReadReplyMessage(ContSock, Buf, 1024, &CancelFlg, TmpBuf) / 100) == FTP_PRELIM)\r
+//                                     ;\r
+                               if(CryptMode == CRYPT_FTPIS)\r
+                               {\r
+                                       if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork, HostData->NoWeakEncryption, Host))\r
+                                       {\r
+                                               while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM)\r
+                                                       ;\r
+                                       }\r
+                                       else\r
+                                               Sts = FTP_ERROR;\r
+                               }\r
+                               else\r
+                               {\r
+                                       while((Sts = ReadReplyMessage(ContSock, Buf, 1024, CancelCheckWork, TmpBuf) / 100) == FTP_PRELIM)\r
+                                               ;\r
+                               }\r
+\r
+                               if(Sts == FTP_COMPLETE)\r
+                               {\r
+                                       Flg = 1;\r
+                                       if(setsockopt(ContSock, SOL_SOCKET, SO_OOBINLINE, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
+                                               ReportWSError("setsockopt", WSAGetLastError());\r
+                                       // データ転送用ソケットのTCP遅延転送が無効されているので念のため\r
+                                       if(setsockopt(ContSock, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
+                                               ReportWSError("setsockopt", WSAGetLastError());\r
+//#pragma aaa\r
+                                       Flg = 1;\r
+                                       if(setsockopt(ContSock, SOL_SOCKET, SO_KEEPALIVE, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
+                                               ReportWSError("setsockopt", WSAGetLastError());\r
+                                       // 切断対策\r
+                                       if(TimeOut > 0)\r
+                                       {\r
+                                               KeepAlive.onoff = 1;\r
+                                               KeepAlive.keepalivetime = TimeOut * 1000;\r
+                                               KeepAlive.keepaliveinterval = 1000;\r
+                                               if(WSAIoctl(ContSock, SIO_KEEPALIVE_VALS, &KeepAlive, sizeof(struct tcp_keepalive), NULL, 0, &dwTmp, NULL, NULL) == SOCKET_ERROR)\r
+                                                       ReportWSError("WSAIoctl", WSAGetLastError());\r
+                                       }\r
+                                       LingerOpt.l_onoff = 1;\r
+                                       LingerOpt.l_linger = 90;\r
+                                       if(setsockopt(ContSock, SOL_SOCKET, SO_LINGER, (LPSTR)&LingerOpt, sizeof(LingerOpt)) == SOCKET_ERROR)\r
+                                               ReportWSError("setsockopt", WSAGetLastError());\r
+///////\r
+\r
+\r
+                                       /*===== 認証を行なう =====*/\r
+\r
+                                       Sts = FTP_COMPLETE;\r
+                                       if((Fwall == FWALL_FU_FP_SITE) ||\r
+                                          (Fwall == FWALL_FU_FP_USER) ||\r
+                                          (Fwall == FWALL_FU_FP))\r
+                                       {\r
+                                               // 同時接続対応\r
+//                                             if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", FwallUser) / 100) == FTP_CONTINUE)\r
+                                               if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", FwallUser) / 100) == FTP_CONTINUE)\r
+                                               {\r
+                                                       CheckOneTimePassword(FwallPass, Reply, FwallSecurity);\r
+                                                       // 同時接続対応\r
+//                                                     Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100;\r
+                                                       Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100;\r
+                                               }\r
+                                       }\r
+                                       else if(Fwall == FWALL_SIDEWINDER)\r
+                                       {\r
+                                               // 同時接続対応\r
+//                                             Sts = command(ContSock, Reply, &CancelFlg, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100;\r
+                                               Sts = command(ContSock, Reply, CancelCheckWork, "USER %s:%s%c%s", FwallUser, FwallPass, FwallDelimiter, Host) / 100;\r
+                                       }\r
+                                       if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE))\r
+                                       {\r
+                                               SetTaskMsg(MSGJPN006);\r
+                                               DoClose(ContSock);\r
+                                               ContSock = INVALID_SOCKET;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               if((Fwall == FWALL_FU_FP_SITE) || (Fwall == FWALL_OPEN))\r
+                                               {\r
+                                                       Flg = 0;\r
+                                                       if(Fwall == FWALL_OPEN)\r
+                                                               Flg = 2;\r
+                                                       if(FwallLower == YES)\r
+                                                               Flg++;\r
+\r
+                                                       if(HostPort == PORT_NOR)\r
+                                                               // 同時接続対応\r
+//                                                             Sts = command(ContSock, NULL, &CancelFlg, "%s %s", SiteTbl[Flg], Host) / 100;\r
+                                                               Sts = command(ContSock, NULL, CancelCheckWork, "%s %s", SiteTbl[Flg], Host) / 100;\r
+                                                       else\r
+                                                               // 同時接続対応\r
+//                                                             Sts = command(ContSock, NULL, &CancelFlg, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100;\r
+                                                               Sts = command(ContSock, NULL, CancelCheckWork, "%s %s %d", SiteTbl[Flg], Host, HostPort) / 100;\r
+                                               }\r
+\r
+                                               if((Sts != FTP_COMPLETE) && (Sts != FTP_CONTINUE))\r
+                                               {\r
+                                                       SetTaskMsg(MSGJPN007, Host);\r
+                                                       DoClose(ContSock);\r
+                                                       ContSock = INVALID_SOCKET;\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       Anony = NO;\r
+                                                       // 同時接続対応\r
+//                                                     if((strlen(User) != 0) || \r
+//                                                        (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
+                                                       if((strlen(User) != 0) || \r
+                                                          ((HostData->NoDisplayUI == NO) && (InputDialogBox(username_dlg, GetMainHwnd(), NULL, User, USER_NAME_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
+                                                       {\r
+                                                               if(Anony == YES)\r
+                                                               {\r
+                                                                       strcpy(User, "anonymous");\r
+                                                                       strcpy(Pass, UserMailAdrs);\r
+                                                               }\r
+\r
+                                                               if((Fwall == FWALL_FU_FP_USER) || (Fwall == FWALL_USER))\r
+                                                               {\r
+                                                                       if(HostPort == PORT_NOR)\r
+                                                                               sprintf(Buf, "%s%c%s", User, FwallDelimiter, Host);\r
+                                                                       else\r
+                                                                               sprintf(Buf, "%s%c%s %d", User, FwallDelimiter, Host, HostPort);\r
+                                                               }\r
+                                                               else\r
+                                                                       strcpy(Buf, User);\r
+\r
+                                                               // FTPES対応\r
+                                                               if(CryptMode == CRYPT_FTPES)\r
+                                                               {\r
+                                                                       if(IsOpenSSLLoaded() && ((Sts = command(ContSock, Reply, CancelCheckWork, "AUTH TLS")) == 234 || (Sts = command(ContSock, Reply, CancelCheckWork, "AUTH SSL")) == 234))\r
+                                                                       {\r
+                                                                               if(AttachSSL(ContSock, INVALID_SOCKET, CancelCheckWork, HostData->NoWeakEncryption, Host))\r
+                                                                               {\r
+                                                                                       if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200)\r
+                                                                                       {\r
+                                                                                               if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200)\r
+                                                                                               {\r
+                                                                                               }\r
+                                                                                               else\r
+                                                                                                       Sts = FTP_ERROR;\r
+                                                                                       }\r
+                                                                                       else\r
+                                                                                               Sts = FTP_ERROR;\r
+                                                                               }\r
+                                                                               else\r
+                                                                                       Sts = FTP_ERROR;\r
+                                                                       }\r
+                                                                       else\r
+                                                                               Sts = FTP_ERROR;\r
+                                                               }\r
+\r
+                                                               // FTPIS対応\r
+                                                               // "PBSZ 0"と"PROT P"は黙示的に設定されているはずだが念のため\r
+                                                               if(CryptMode == CRYPT_FTPIS)\r
+                                                               {\r
+                                                                       if((Sts = command(ContSock, Reply, CancelCheckWork, "PBSZ 0")) == 200)\r
+                                                                       {\r
+                                                                               if((Sts = command(ContSock, Reply, CancelCheckWork, "PROT P")) == 200)\r
+                                                                               {\r
+                                                                               }\r
+                                                                       }\r
+                                                               }\r
+\r
+                                                               ReInPass = NO;\r
+                                                               do\r
+                                                               {\r
+                                                                       // FTPES対応\r
+                                                                       if(Sts == FTP_ERROR)\r
+                                                                               break;\r
+                                                                       Continue = NO;\r
+                                                                       // 同時接続対応\r
+//                                                                     if((Sts = command(ContSock, Reply, &CancelFlg, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
+                                                                       if((Sts = command(ContSock, Reply, CancelCheckWork, "USER %s", Buf) / 100) == FTP_CONTINUE)\r
+                                                                       {\r
+                                                                               // 同時接続対応\r
+//                                                                             if((strlen(Pass) != 0) || \r
+//                                                                                (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
+                                                                               if((strlen(Pass) != 0) || \r
+                                                                                  ((HostData->NoDisplayUI == NO) && (InputDialogBox(passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
+                                                                               {\r
+                                                                                       CheckOneTimePassword(Pass, Reply, Security);\r
+\r
+                                                                                       /* パスワードがスペース1個の時はパスワードの実体なしとする */\r
+                                                                                       if(strcmp(Reply, " ") == 0)\r
+                                                                                               strcpy(Reply, "");\r
+\r
+                                                                                       // 同時接続対応\r
+//                                                                                     Sts = command(ContSock, NULL, &CancelFlg, "PASS %s", Reply) / 100;\r
+                                                                                       Sts = command(ContSock, NULL, CancelCheckWork, "PASS %s", Reply) / 100;\r
+                                                                                       if(Sts == FTP_ERROR)\r
+                                                                                       {\r
+                                                                                               strcpy(Pass, "");\r
+                                                                                               // 同時接続対応\r
+//                                                                                             if(InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)\r
+                                                                                               if(HostData->NoDisplayUI == NO && InputDialogBox(re_passwd_dlg, GetMainHwnd(), NULL, Pass, PASSWORD_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)\r
+                                                                                                       Continue = YES;\r
+                                                                                               else\r
+                                                                                                       DoPrintf("No password specified.");\r
+                                                                                               ReInPass = YES;\r
+                                                                                       }\r
+                                                                                       else if(Sts == FTP_CONTINUE)\r
+                                                                                       {\r
+                                                                                               // 同時接続対応\r
+//                                                                                             if((strlen(Acct) != 0) || \r
+//                                                                                                (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES))\r
+                                                                                               if((strlen(Acct) != 0) || \r
+                                                                                                  ((HostData->NoDisplayUI == NO) && (InputDialogBox(account_dlg, GetMainHwnd(), NULL, Acct, ACCOUNT_LEN+1, &Anony, IDH_HELP_TOPIC_0000001) == YES)))\r
+                                                                                               {\r
+                                                                                                       // 同時接続対応\r
+//                                                                                                     Sts = command(ContSock, NULL, &CancelFlg, "ACCT %s", Acct) / 100;\r
+                                                                                                       Sts = command(ContSock, NULL, CancelCheckWork, "ACCT %s", Acct) / 100;\r
+                                                                                               }\r
+                                                                                               else\r
+                                                                                                       DoPrintf("No account specified");\r
+                                                                                       }\r
+                                                                               }\r
+                                                                               else\r
+                                                                               {\r
+                                                                                       Sts = FTP_ERROR;\r
+                                                                                       DoPrintf("No password specified.");\r
+                                                                               }\r
+                                                                       }\r
+                                                                       // FTPES対応\r
+                                                                       if(Continue == YES)\r
+                                                                               Sts = FTP_COMPLETE;\r
+                                                               }\r
+                                                               while(Continue == YES);\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                               Sts = FTP_ERROR;\r
+                                                               DoPrintf("No user name specified");\r
+                                                       }\r
+\r
+                                                       if(Sts != FTP_COMPLETE)\r
+                                                       {\r
+                                                               SetTaskMsg(MSGJPN008, Host);\r
+                                                               DoClose(ContSock);\r
+                                                               ContSock = INVALID_SOCKET;\r
+                                                       }\r
+                                                       else if((SavePass == YES) && (ReInPass == YES))\r
+                                                       {\r
+                                                               // 同時接続対応\r
+//                                                             if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
+                                                               if(HostData->NoDisplayUI == NO && DialogBox(GetFtpInst(), MAKEINTRESOURCE(savepass_dlg), GetMainHwnd(), ExeEscDialogProc) == YES)\r
+                                                                       SetHostPassword(AskCurrentHost(), Pass);\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+//#pragma aaa\r
+                                       SetTaskMsg(MSGJPN009/*"接続できません(1) %x", ContSock*/);\r
+                                       DoClose(ContSock);\r
+                                       ContSock = INVALID_SOCKET;\r
+                               }\r
+                       }\r
+               }\r
+               else\r
+               {\r
+\r
+                       if(((Fwall >= FWALL_FU_FP_SITE) && (Fwall <= FWALL_OPEN)) ||\r
+                          (Fwall == FWALL_FU_FP))\r
+                               SetTaskMsg(MSGJPN010);\r
+                       else\r
+                               SetTaskMsg(MSGJPN011);\r
+               }\r
+\r
+#if 0\r
+//             WSAUnhookBlockingHook();\r
+#endif\r
+               TryConnect = NO;\r
+\r
+               // FEAT対応\r
+               // ホストの機能を確認\r
+               if(ContSock != INVALID_SOCKET)\r
+               {\r
+                       if((Sts = command(ContSock, Reply, CancelCheckWork, "FEAT")) == 211)\r
+                       {\r
+                               // 改行文字はReadReplyMessageで消去されるため区切り文字に空白を使用\r
+                               // UTF-8対応\r
+                               if(strstr(Reply, " UTF8 "))\r
+                                       HostData->Feature |= FEATURE_UTF8;\r
+                               // MLST対応\r
+                               if(strstr(Reply, " MLST ") || strstr(Reply, " MLSD "))\r
+                                       HostData->Feature |= FEATURE_MLSD;\r
+                               // IPv6対応\r
+                               if(strstr(Reply, " EPRT ") || strstr(Reply, " EPSV "))\r
+                                       HostData->Feature |= FEATURE_EPRT | FEATURE_EPSV;\r
+                               // ホスト側の日時取得\r
+                               if(strstr(Reply, " MDTM "))\r
+                                       HostData->Feature |= FEATURE_MDTM;\r
+                               // ホスト側の日時設定\r
+                               if(strstr(Reply, " MFMT "))\r
+                                       HostData->Feature |= FEATURE_MFMT;\r
+                       }\r
+                       // UTF-8対応\r
+                       if(HostData->CurNameKanjiCode == KANJI_AUTO && (HostData->Feature & FEATURE_UTF8))\r
+                       {\r
+                               // UTF-8を指定した場合も自動判別を行う\r
+//                             if((Sts = command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON")) == 200)\r
+//                                     HostData->CurNameKanjiCode = KANJI_UTF8N;\r
+                               command(ContSock, Reply, CancelCheckWork, "OPTS UTF8 ON");\r
+                       }\r
+               }\r
+       }\r
+\r
+       return(ContSock);\r
+}\r
+\r
+// 同時接続対応\r
+//static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security)\r
+static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass, char *Acct, int Port, int Fwall, int SavePass, int Security, int *CancelCheckWork)\r
+{\r
+       SOCKET ContSock;\r
+       ContSock = INVALID_SOCKET;\r
+       *CancelCheckWork = NO;\r
+       if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES)\r
+       {\r
+               SetTaskMsg(MSGJPN316);\r
+               if((ContSock = DoConnectCrypt(CRYPT_FTPIS, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
+                       HostData->CryptMode = CRYPT_FTPIS;\r
+       }\r
+       if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPES == YES)\r
+       {\r
+               SetTaskMsg(MSGJPN315);\r
+               if((ContSock = DoConnectCrypt(CRYPT_FTPES, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
+                       HostData->CryptMode = CRYPT_FTPES;\r
+       }\r
+       if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseNoEncryption == YES)\r
+       {\r
+               SetTaskMsg(MSGJPN314);\r
+               if((ContSock = DoConnectCrypt(CRYPT_NONE, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
+                       HostData->CryptMode = CRYPT_NONE;\r
+       }\r
+       return ContSock;\r
+}\r
+\r
+\r
+/*----- ワンタイムパスワードのチェック ----------------------------------------\r
+*\r
+*      Parameter\r
+*              chat *Pass : パスワード/パスフレーズ\r
+*              char *Reply : USERコマンドを送ったあとのリプライ文字列\r
+*                                              /PASSコマンドで送るパスワードを返すバッファ\r
+*              int Type : タイプ (SECURITY_xxx, MDx)\r
+*\r
+*      Return Value\r
+*              int ステータス\r
+*                      FFFTP_SUCCESS/FFFTP_FAIL\r
+*\r
+*      Note\r
+*              ワンタイムパスワードでない時はPassをそのままReplyにコピー\r
+*----------------------------------------------------------------------------*/\r
+\r
+static int CheckOneTimePassword(char *Pass, char *Reply, int Type)\r
+{\r
+       int Sts;\r
+       char *Pos;\r
+       int Seq;\r
+       char Seed[MAX_SEED_LEN+1];\r
+       int i;\r
+\r
+       Sts = FFFTP_SUCCESS;\r
+       Pos = NULL;\r
+\r
+       if(Type == SECURITY_AUTO)\r
+       {\r
+               if((Pos = stristr(Reply, "otp-md5")) != NULL)\r
+               {\r
+                       Type = MD5;\r
+                       SetTaskMsg(MSGJPN012);\r
+               }\r
+               else if((Pos = stristr(Reply, "otp-sha1")) != NULL)\r
+               {\r
+                       Type = SHA1;\r
+                       SetTaskMsg(MSGJPN013);\r
+               }\r
+               else if(((Pos = stristr(Reply, "otp-md4")) != NULL) || ((Pos = stristr(Reply, "s/key")) != NULL))\r
+               {\r
+                       Type = MD4;\r
+                       SetTaskMsg(MSGJPN014);\r
+               }\r
+       }\r
+       else\r
+               Pos = GetNextField(Reply);\r
+\r
+       if((Type == MD4) || (Type == MD5) || (Type == SHA1))\r
+       {\r
+               /* シーケンス番号を見つけるループ */\r
+               DoPrintf("Analyze OTP");\r
+               DoPrintf("%s", Pos);\r
+               Sts = FFFTP_FAIL;\r
+               while((Pos = GetNextField(Pos)) != NULL)\r
+               {\r
+                       if(IsDigit(*Pos))\r
+                       {\r
+                               Seq = atoi(Pos);\r
+                               DoPrintf("Sequence=%d", Seq);\r
+\r
+                               /* Seed */\r
+                               if((Pos = GetNextField(Pos)) != NULL)\r
+                               {\r
+                                       if(GetOneField(Pos, Seed, MAX_SEED_LEN) == FFFTP_SUCCESS)\r
+                                       {\r
+                                               /* Seedは英数字のみ有効とする */\r
+                                               for(i = strlen(Seed)-1; i >= 0; i--)\r
+                                               {\r
+                                                       if((IsAlpha(Seed[i]) == 0) && (IsDigit(Seed[i]) == 0))\r
+                                                               Seed[i] = NUL;\r
+                                               }\r
+                                               if(strlen(Seed) > 0)\r
+                                               {\r
+                                                       DoPrintf("Seed=%s", Seed);\r
+                                                       Make6WordPass(Seq, Seed, Pass, Type, Reply);\r
+                                                       DoPrintf("Response=%s", Reply);\r
+\r
+                                                       /* シーケンス番号のチェックと警告 */\r
+                                                       if(Seq <= 10)\r
+                                                               DialogBox(GetFtpInst(), MAKEINTRESOURCE(otp_notify_dlg), GetMainHwnd(), ExeEscDialogProc);\r
+\r
+                                                       Sts = FFFTP_SUCCESS;\r
+                                               }\r
+                                       }\r
+                               }\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               if(Sts == FFFTP_FAIL)\r
+                       SetTaskMsg(MSGJPN015);\r
+       }\r
+       else\r
+       {\r
+               strcpy(Reply, Pass);\r
+               DoPrintf("No OTP used.");\r
+       }\r
+       return(Sts);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/*----- ソケットを接続する ----------------------------------------------------\r
+*\r
+*      Parameter\r
+*              char *host : ホスト名\r
+*              int port : ポート番号\r
+*              char *PreMsg : メッセージの前半部分\r
+*\r
+*      Return Value\r
+*              SOCKET ソケット\r
+*----------------------------------------------------------------------------*/\r
+\r
+// IPv6対応\r
+typedef SOCKET (__cdecl* LPCONNECTSOCK)(char*, int, char*, int*);\r
+\r
+typedef struct\r
+{\r
+       HANDLE h;\r
+       DWORD ExitCode;\r
+       char *host;\r
+       int port;\r
+       char *PreMsg;\r
+       int CancelCheckWork;\r
+       LPCONNECTSOCK f;\r
+       SOCKET s;\r
+} CONNECTSOCKDATA;\r
+\r
+DWORD WINAPI connectsockThreadProc(LPVOID lpParameter)\r
+{\r
+       CONNECTSOCKDATA* pData;\r
+       pData = (CONNECTSOCKDATA*)lpParameter;\r
+       pData->s = pData->f(pData->host, pData->port, pData->PreMsg, &pData->CancelCheckWork);\r
+       return 0;\r
+}\r
+\r
+// IPv6対応\r
+SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
+{\r
+       SOCKET Result;\r
+       CONNECTSOCKDATA DataIPv4;\r
+       CONNECTSOCKDATA DataIPv6;\r
+       Result = INVALID_SOCKET;\r
+       switch(CurHost.CurNetType)\r
+       {\r
+       case NTYPE_AUTO:\r
+//             if((Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
+//                     CurHost.CurNetType = NTYPE_IPV4;\r
+//             else if((Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork)) != INVALID_SOCKET)\r
+//                     CurHost.CurNetType = NTYPE_IPV6;\r
+               DataIPv4.host = host;\r
+               DataIPv4.port = port;\r
+               DataIPv4.PreMsg = PreMsg;\r
+               DataIPv4.CancelCheckWork = *CancelCheckWork;\r
+               DataIPv4.f = connectsockIPv4;\r
+               DataIPv4.h = CreateThread(NULL, 0, connectsockThreadProc, &DataIPv4, 0, NULL);\r
+               DataIPv6.host = host;\r
+               DataIPv6.port = port;\r
+               DataIPv6.PreMsg = PreMsg;\r
+               DataIPv6.CancelCheckWork = *CancelCheckWork;\r
+               DataIPv6.f = connectsockIPv6;\r
+               DataIPv6.h = CreateThread(NULL, 0, connectsockThreadProc, &DataIPv6, 0, NULL);\r
+               while(1)\r
+               {\r
+                       if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode))\r
+                       {\r
+                               if(DataIPv4.ExitCode != STILL_ACTIVE)\r
+                               {\r
+                                       if(DataIPv4.s != INVALID_SOCKET)\r
+                                       {\r
+                                               Result = DataIPv4.s;\r
+                                               CurHost.CurNetType = NTYPE_IPV4;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+                       if(GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
+                       {\r
+                               if(DataIPv6.ExitCode != STILL_ACTIVE)\r
+                               {\r
+                                       if(DataIPv6.s != INVALID_SOCKET)\r
+                                       {\r
+                                               Result = DataIPv6.s;\r
+                                               CurHost.CurNetType = NTYPE_IPV6;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+                       if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode) && GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
+                       {\r
+                               if(DataIPv4.ExitCode != STILL_ACTIVE && DataIPv6.ExitCode != STILL_ACTIVE)\r
+                               {\r
+                                       if(DataIPv4.s == INVALID_SOCKET && DataIPv6.s == INVALID_SOCKET)\r
+                                               break;\r
+                               }\r
+                       }\r
+                       DataIPv4.CancelCheckWork = *CancelCheckWork;\r
+                       DataIPv6.CancelCheckWork = *CancelCheckWork;\r
+                       BackgrndMessageProc();\r
+                       Sleep(1);\r
+               }\r
+               while(1)\r
+               {\r
+                       if(GetExitCodeThread(DataIPv4.h, &DataIPv4.ExitCode) && GetExitCodeThread(DataIPv6.h, &DataIPv6.ExitCode))\r
+                       {\r
+                               if(DataIPv4.ExitCode != STILL_ACTIVE && DataIPv6.ExitCode != STILL_ACTIVE)\r
+                               {\r
+                                       CloseHandle(DataIPv4.h);\r
+                                       CloseHandle(DataIPv6.h);\r
+                                       break;\r
+                               }\r
+                       }\r
+                       DataIPv4.CancelCheckWork = YES;\r
+                       DataIPv6.CancelCheckWork = YES;\r
+                       BackgrndMessageProc();\r
+                       Sleep(1);\r
+               }\r
+               break;\r
+       case NTYPE_IPV4:\r
+               Result = connectsockIPv4(host, port, PreMsg, CancelCheckWork);\r
+               CurHost.CurNetType = NTYPE_IPV4;\r
+               break;\r
+       case NTYPE_IPV6:\r
+               Result = connectsockIPv6(host, port, PreMsg, CancelCheckWork);\r
+               CurHost.CurNetType = NTYPE_IPV6;\r
+               break;\r
+       }\r
+       return Result;\r
+}\r
+\r
+\r
+// IPv6対応\r
+//SOCKET connectsock(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
+SOCKET connectsockIPv4(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
+{\r
+       // IPv6対応\r
+       struct sockaddr_in SocksSockAddr;       /* SOCKSサーバのアドレス情報 */\r
+       struct sockaddr_in CurSockAddr;         /* 接続先ホストのアドレス情報 */\r
+       struct sockaddr_in saSockAddr;\r
+       char HostEntry[MAXGETHOSTSTRUCT];\r
+       struct hostent *pHostEntry;\r
+       SOCKET sSocket;\r
+       int Len;\r
+       int Fwall;\r
+       SOCKS4CMD Socks4Cmd;\r
+       SOCKS4REPLY Socks4Reply;\r
+       SOCKS5REQUEST Socks5Cmd;\r
+       SOCKS5REPLY Socks5Reply;\r
+\r
+       //////////////////////////////\r
+       // ホスト名解決と接続の準備\r
+       //////////////////////////////\r
+\r
+       Fwall = FWALL_NONE;\r
+       if(AskHostFireWall() == YES)\r
+               Fwall = FwallType;\r
+\r
+       sSocket = INVALID_SOCKET;\r
+\r
+       UseIPadrs = YES;\r
+       strcpy(DomainName, host);\r
+       memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
+       CurSockAddr.sin_port = htons((u_short)port);\r
+       CurSockAddr.sin_family = AF_INET;\r
+       if((CurSockAddr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)\r
+       {\r
+               // ホスト名が指定された\r
+               // ホスト名からアドレスを求める\r
+               if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
+                  (FwallResolve == YES))\r
+               {\r
+                       // ホスト名解決はSOCKSサーバに任せる\r
+                       pHostEntry = NULL;\r
+               }\r
+               else\r
+               {\r
+                       // アドレスを取得\r
+                       // IPv6対応\r
+//                     SetTaskMsg(MSGJPN016, DomainName);\r
+                       SetTaskMsg(MSGJPN016, DomainName, MSGJPN333);\r
+                       // IPv6対応\r
+//                     pHostEntry = do_gethostbyname(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
+                       pHostEntry = do_gethostbynameIPv4(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
+               }\r
+\r
+               if(pHostEntry != NULL)\r
+               {\r
+                       memcpy((char *)&CurSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+                       // IPv6対応\r
+//                     SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
+                       SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port), MSGJPN333);\r
+               }\r
+               else\r
+               {\r
+                       if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+                       {\r
+                               UseIPadrs = NO;\r
+                               // IPv6対応\r
+//                             SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port));\r
+                               SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin_port), MSGJPN333);\r
+                       }\r
+                       else\r
+                       {\r
+                               // IPv6対応\r
+//                             SetTaskMsg(MSGJPN019, host);\r
+                               SetTaskMsg(MSGJPN019, host, MSGJPN333);\r
+                               return(INVALID_SOCKET);\r
+                       }\r
+               }\r
+       }\r
+       else\r
+               // IPv6対応\r
+//             SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port));\r
+               SetTaskMsg(MSGJPN020, PreMsg, inet_ntoa(CurSockAddr.sin_addr), ntohs(CurSockAddr.sin_port), MSGJPN333);\r
+\r
+       if((Fwall == FWALL_SOCKS4) || (Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+       {\r
+               // SOCKSを使う\r
+               // SOCKSに接続する準備\r
+               if(Fwall == FWALL_SOCKS4)\r
+               {\r
+                       Socks4Cmd.Ver = SOCKS4_VER;\r
+                       Socks4Cmd.Cmd = SOCKS4_CMD_CONNECT;\r
+                       Socks4Cmd.Port = CurSockAddr.sin_port;\r
+                       Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
+                       strcpy(Socks4Cmd.UserID, FwallUser);\r
+                       Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
+               }\r
+               else\r
+               {\r
+                       Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
+               }\r
+\r
+               memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
+               if((SocksSockAddr.sin_addr.s_addr = inet_addr(FwallHost)) == INADDR_NONE)\r
+               {\r
+                       // IPv6対応\r
+//                     if((pHostEntry = do_gethostbyname(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
+                       if((pHostEntry = do_gethostbynameIPv4(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
+                               memcpy((char *)&SocksSockAddr.sin_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+                       else\r
+                       {\r
+                               // IPv6対応\r
+//                             SetTaskMsg(MSGJPN021, FwallHost);\r
+                               SetTaskMsg(MSGJPN021, FwallHost, MSGJPN333);\r
+                               return INVALID_SOCKET;\r
+                       }\r
+               }\r
+               SocksSockAddr.sin_port = htons((u_short)FwallPort);\r
+               SocksSockAddr.sin_family = AF_INET;\r
+               // IPv6対応\r
+//             SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port));\r
+               SetTaskMsg(MSGJPN022, inet_ntoa(SocksSockAddr.sin_addr), ntohs(SocksSockAddr.sin_port), MSGJPN333);\r
+               // connectで接続する先はSOCKSサーバ\r
+               memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
+       }\r
+       else\r
+       {\r
+               // connectで接続するのは接続先のホスト\r
+               memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
+       }\r
+\r
+       /////////////\r
+       // 接続実行\r
+       /////////////\r
+\r
+       if((sSocket = do_socket(AF_INET, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
+       {\r
+               // ソケットにデータを付与\r
+               SetAsyncTableDataIPv4(sSocket, &CurSockAddr, &SocksSockAddr);\r
+               if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+               {\r
+                       if(Fwall == FWALL_SOCKS4)\r
+                       {\r
+                               Socks4Reply.Result = -1;\r
+                               // 同時接続対応\r
+//                             if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//                                (Socks4GetCmdReply(sSocket, &Socks4Reply) != FFFTP_SUCCESS) || \r
+//                                (Socks4Reply.Result != SOCKS4_RES_OK))\r
+                               if((SocksSendCmd(sSocket, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                                  (Socks4GetCmdReply(sSocket, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
+                                  (Socks4Reply.Result != SOCKS4_RES_OK))\r
+                               {\r
+                                       // IPv6対応\r
+//                                     SetTaskMsg(MSGJPN023, Socks4Reply.Result);\r
+                                       SetTaskMsg(MSGJPN023, Socks4Reply.Result, MSGJPN333);\r
+                                       DoClose(sSocket);\r
+                                       sSocket = INVALID_SOCKET;\r
+                               }\r
+                       }\r
+                       else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+                       {\r
+                               if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
+                               {\r
+                                       DoClose(sSocket);\r
+                                       sSocket = INVALID_SOCKET;\r
+                               }\r
+\r
+                               Socks5Reply.Result = -1;\r
+                               // 同時接続対応\r
+//                             if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//                                (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
+//                                (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                                  (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
+                                  (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               {\r
+                                       // IPv6対応\r
+//                                     SetTaskMsg(MSGJPN024, Socks5Reply.Result);\r
+                                       SetTaskMsg(MSGJPN024, Socks5Reply.Result, MSGJPN333);\r
+                                       DoClose(sSocket);\r
+                                       sSocket = INVALID_SOCKET;\r
+                               }\r
+\r
+                       }\r
+\r
+                       if(sSocket != INVALID_SOCKET)\r
+                               // IPv6対応\r
+//                             SetTaskMsg(MSGJPN025);\r
+                               SetTaskMsg(MSGJPN025, MSGJPN333);\r
+               }\r
+               else\r
+               {\r
+//#pragma aaa\r
+                       // IPv6対応\r
+//                     SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/);\r
+                       SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/, MSGJPN333);\r
+                       DoClose(sSocket);\r
+                       sSocket = INVALID_SOCKET;\r
+               }\r
+       }\r
+       else\r
+               // IPv6対応\r
+//             SetTaskMsg(MSGJPN027);\r
+               SetTaskMsg(MSGJPN027, MSGJPN333);\r
+\r
+       return(sSocket);\r
+}\r
+\r
+\r
+SOCKET connectsockIPv6(char *host, int port, char *PreMsg, int *CancelCheckWork)\r
+{\r
+       struct sockaddr_in6 SocksSockAddr;      /* SOCKSサーバのアドレス情報 */\r
+       struct sockaddr_in6 CurSockAddr;                /* 接続先ホストのアドレス情報 */\r
+       struct sockaddr_in6 saSockAddr;\r
+       char HostEntry[MAXGETHOSTSTRUCT];\r
+       struct hostent *pHostEntry;\r
+       SOCKET sSocket;\r
+       int Len;\r
+       int Fwall;\r
+       SOCKS5REQUEST Socks5Cmd;\r
+       SOCKS5REPLY Socks5Reply;\r
+\r
+       //////////////////////////////\r
+       // ホスト名解決と接続の準備\r
+       //////////////////////////////\r
+\r
+       Fwall = FWALL_NONE;\r
+       if(AskHostFireWall() == YES)\r
+               Fwall = FwallType;\r
+\r
+       sSocket = INVALID_SOCKET;\r
+\r
+       UseIPadrs = YES;\r
+       strcpy(DomainName, host);\r
+       memset(&CurSockAddr, 0, sizeof(CurSockAddr));\r
+       CurSockAddr.sin6_port = htons((u_short)port);\r
+       CurSockAddr.sin6_family = AF_INET6;\r
+       CurSockAddr.sin6_addr = inet6_addr(host);\r
+       if(memcmp(&CurSockAddr.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
+       {\r
+               // ホスト名が指定された\r
+               // ホスト名からアドレスを求める\r
+               if(((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER)) &&\r
+                  (FwallResolve == YES))\r
+               {\r
+                       // ホスト名解決はSOCKSサーバに任せる\r
+                       pHostEntry = NULL;\r
+               }\r
+               else\r
+               {\r
+                       // アドレスを取得\r
+                       SetTaskMsg(MSGJPN016, DomainName, MSGJPN334);\r
+                       pHostEntry = do_gethostbynameIPv6(host, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork);\r
+               }\r
+\r
+               if(pHostEntry != NULL)\r
+               {\r
+                       memcpy((char *)&CurSockAddr.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+                       SetTaskMsg(MSGJPN017, PreMsg, DomainName, inet6_ntoa(CurSockAddr.sin6_addr), ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
+               }\r
+               else\r
+               {\r
+                       if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+                       {\r
+                               UseIPadrs = NO;\r
+                               SetTaskMsg(MSGJPN018, PreMsg, DomainName, ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
+                       }\r
+                       else\r
+                       {\r
+                               SetTaskMsg(MSGJPN019, host, MSGJPN334);\r
+                               return(INVALID_SOCKET);\r
+                       }\r
+               }\r
+       }\r
+       else\r
+               SetTaskMsg(MSGJPN020, PreMsg, inet6_ntoa(CurSockAddr.sin6_addr), ntohs(CurSockAddr.sin6_port), MSGJPN334);\r
+\r
+       if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+       {\r
+               // SOCKSを使う\r
+               // SOCKSに接続する準備\r
+               {\r
+                       Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_CONNECT, UseIPadrs, (char*)&CurSockAddr.sin6_addr, DomainName, CurSockAddr.sin6_port);\r
+               }\r
+\r
+               memset(&SocksSockAddr, 0, sizeof(SocksSockAddr));\r
+               SocksSockAddr.sin6_addr = inet6_addr(FwallHost);\r
+               if(memcmp(&SocksSockAddr.sin6_addr, &IN6ADDR_NONE, sizeof(struct in6_addr)) == 0)\r
+               {\r
+                       if((pHostEntry = do_gethostbynameIPv6(FwallHost, HostEntry, MAXGETHOSTSTRUCT, CancelCheckWork)) != NULL)\r
+                               memcpy((char *)&SocksSockAddr.sin6_addr, pHostEntry->h_addr, pHostEntry->h_length);\r
+                       else\r
+                       {\r
+                               SetTaskMsg(MSGJPN021, FwallHost, MSGJPN334);\r
+                               return INVALID_SOCKET;\r
+                       }\r
+               }\r
+               SocksSockAddr.sin6_port = htons((u_short)FwallPort);\r
+               SocksSockAddr.sin6_family = AF_INET6;\r
+               SetTaskMsg(MSGJPN022, inet6_ntoa(SocksSockAddr.sin6_addr), ntohs(SocksSockAddr.sin6_port), MSGJPN334);\r
+               // connectで接続する先はSOCKSサーバ\r
+               memcpy(&saSockAddr, &SocksSockAddr, sizeof(SocksSockAddr));\r
+       }\r
+       else\r
+       {\r
+               // connectで接続するのは接続先のホスト\r
+               memcpy(&saSockAddr, &CurSockAddr, sizeof(CurSockAddr));\r
+       }\r
+\r
+       /////////////\r
+       // 接続実行\r
+       /////////////\r
+\r
+       if((sSocket = do_socket(AF_INET6, SOCK_STREAM, TCP_PORT)) != INVALID_SOCKET)\r
+       {\r
+               // ソケットにデータを付与\r
+               SetAsyncTableDataIPv6(sSocket, &CurSockAddr, &SocksSockAddr);\r
+               if(do_connect(sSocket, (struct sockaddr *)&saSockAddr, sizeof(saSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+               {\r
+                       if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+                       {\r
+                               if(Socks5SelMethod(sSocket, CancelCheckWork) == FFFTP_FAIL)\r
+                               {\r
+                                       DoClose(sSocket);\r
+                                       sSocket = INVALID_SOCKET;\r
+                               }\r
+\r
+                               Socks5Reply.Result = -1;\r
+                               // 同時接続対応\r
+//                             if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//                                (Socks5GetCmdReply(sSocket, &Socks5Reply) != FFFTP_SUCCESS) || \r
+//                                (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               if((SocksSendCmd(sSocket, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                                  (Socks5GetCmdReply(sSocket, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
+                                  (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               {\r
+                                       SetTaskMsg(MSGJPN024, Socks5Reply.Result, MSGJPN334);\r
+                                       DoClose(sSocket);\r
+                                       sSocket = INVALID_SOCKET;\r
+                               }\r
+\r
+                       }\r
+\r
+                       if(sSocket != INVALID_SOCKET)\r
+                               SetTaskMsg(MSGJPN025, MSGJPN334);\r
+               }\r
+               else\r
+               {\r
+//#pragma aaa\r
+                       SetTaskMsg(MSGJPN026/*"接続できません(2) %x", sSocket*/, MSGJPN334);\r
+                       DoClose(sSocket);\r
+                       sSocket = INVALID_SOCKET;\r
+               }\r
+       }\r
+       else\r
+               SetTaskMsg(MSGJPN027, MSGJPN334);\r
+\r
+       return(sSocket);\r
+}\r
+\r
+\r
+/*----- リッスンソケットを取得 ------------------------------------------------\r
+*\r
+*      Parameter\r
+*              SOCKET ctrl_skt : コントロールソケット\r
+*\r
+*      Return Value\r
+*              SOCKET リッスンソケット\r
+*----------------------------------------------------------------------------*/\r
+\r
+// IPv6対応\r
+SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
+{\r
+       SOCKET Result;\r
+       Result = INVALID_SOCKET;\r
+       switch(CurHost.CurNetType)\r
+       {\r
+       case NTYPE_IPV4:\r
+               Result = GetFTPListenSocketIPv4(ctrl_skt, CancelCheckWork);\r
+               break;\r
+       case NTYPE_IPV6:\r
+               Result = GetFTPListenSocketIPv6(ctrl_skt, CancelCheckWork);\r
+               break;\r
+       }\r
+       return Result;\r
+}\r
+\r
+\r
+// IPv6対応\r
+//SOCKET GetFTPListenSocket(SOCKET ctrl_skt, int *CancelCheckWork)\r
+SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork)\r
+{\r
+       // IPv6対応\r
+       struct sockaddr_in SocksSockAddr;       /* SOCKSサーバのアドレス情報 */\r
+       struct sockaddr_in CurSockAddr;         /* 接続先ホストのアドレス情報 */\r
+       SOCKET listen_skt;\r
+       int iLength;\r
+       char *a,*p;\r
+       struct sockaddr_in saCtrlAddr;\r
+       struct sockaddr_in saTmpAddr;\r
+       SOCKS4CMD Socks4Cmd;\r
+       SOCKS4REPLY Socks4Reply;\r
+       SOCKS5REQUEST Socks5Cmd;\r
+       SOCKS5REPLY Socks5Reply;\r
+\r
+       int Len;\r
+       int Fwall;\r
+\r
+       // UPnP対応\r
+       char Adrs[16];\r
+       int Port;\r
+       char ExtAdrs[40];\r
+\r
+       // ソケットにデータを付与\r
+       GetAsyncTableDataIPv4(ctrl_skt, &CurSockAddr, &SocksSockAddr);\r
+\r
+       Fwall = FWALL_NONE;\r
+       if(AskHostFireWall() == YES)\r
+               Fwall = FwallType;\r
+\r
+       if((listen_skt = do_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
+       {\r
+               if(Fwall == FWALL_SOCKS4)\r
+               {\r
+                       /*===== SOCKS4を使う =====*/\r
+                       DoPrintf("Use SOCKS4 BIND");\r
+                       if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+                       {\r
+                               Socks4Cmd.Ver = SOCKS4_VER;\r
+                               Socks4Cmd.Cmd = SOCKS4_CMD_BIND;\r
+                               Socks4Cmd.Port = CurSockAddr.sin_port;\r
+                               Socks4Cmd.AdrsInt = CurSockAddr.sin_addr.s_addr;\r
+                               strcpy(Socks4Cmd.UserID, FwallUser);\r
+                               Len = offsetof(SOCKS4CMD, UserID) + strlen(FwallUser) + 1;\r
+\r
+                               Socks4Reply.Result = -1;\r
+                               // 同時接続対応\r
+//                             if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//                                (Socks4GetCmdReply(listen_skt, &Socks4Reply) != FFFTP_SUCCESS) || \r
+//                                (Socks4Reply.Result != SOCKS4_RES_OK))\r
+                               if((SocksSendCmd(listen_skt, &Socks4Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                                  (Socks4GetCmdReply(listen_skt, &Socks4Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
+                                  (Socks4Reply.Result != SOCKS4_RES_OK))\r
+                               {\r
+                                       // IPv6対応\r
+//                                     SetTaskMsg(MSGJPN028, Socks4Reply.Result);\r
+                                       SetTaskMsg(MSGJPN028, Socks4Reply.Result, MSGJPN333);\r
+                                       DoClose(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                               }\r
+\r
+                               if(Socks4Reply.AdrsInt == 0)\r
+                                       Socks4Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
+\r
+                               a = (char *)&Socks4Reply.AdrsInt;\r
+                               p = (char *)&Socks4Reply.Port;\r
+                       }\r
+               }\r
+               else if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+               {\r
+                       /*===== SOCKS5を使う =====*/\r
+                       DoPrintf("Use SOCKS5 BIND");\r
+                       if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+                       {\r
+                               if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
+                               {\r
+                                       DoClose(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                                       return(listen_skt);\r
+                               }\r
+\r
+                               Len = Socks5MakeCmdPacket(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, CurSockAddr.sin_addr.s_addr, DomainName, CurSockAddr.sin_port);\r
+\r
+                               Socks5Reply.Result = -1;\r
+                               // 同時接続対応\r
+//                             if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//                                (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
+//                                (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                                  (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
+                                  (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               {\r
+                                       // IPv6対応\r
+//                                     SetTaskMsg(MSGJPN029, Socks5Reply.Result);\r
+                                       SetTaskMsg(MSGJPN029, Socks5Reply.Result, MSGJPN333);\r
+                                       DoClose(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                               }\r
+\r
+                               // IPv6対応\r
+//                             if(Socks5Reply.AdrsInt == 0)\r
+//                                     Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
+\r
+                               // IPv6対応\r
+//                             a = (char *)&Socks5Reply.AdrsInt;\r
+//                             p = (char *)&Socks5Reply.Port;\r
+                               a = (char *)&Socks5Reply._dummy[0];\r
+                               p = (char *)&Socks5Reply._dummy[4];\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       /*===== SOCKSを使わない =====*/\r
+                       DoPrintf("Use normal BIND");\r
+                       saCtrlAddr.sin_port = htons(0);\r
+                       saCtrlAddr.sin_family = AF_INET;\r
+                       saCtrlAddr.sin_addr.s_addr = 0;\r
+\r
+                       if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr)) != SOCKET_ERROR)\r
+                       {\r
+                               iLength = sizeof(saCtrlAddr);\r
+                               if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
+                               {\r
+                                       if(do_listen(listen_skt, 1) == 0)\r
+                                       {\r
+                                               iLength = sizeof(saTmpAddr);\r
+                                               if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
+                                                       ReportWSError("getsockname", WSAGetLastError());\r
+\r
+                                               a = (char *)&saTmpAddr.sin_addr;\r
+                                               p = (char *)&saCtrlAddr.sin_port;\r
+                                               // UPnP対応\r
+                                               if(IsUPnPLoaded() == YES && UPnPEnabled == YES)\r
+                                               {\r
+                                                       if(AddPortMapping(AddressToStringIPv4(Adrs, &saTmpAddr.sin_addr), ntohs(saCtrlAddr.sin_port), ExtAdrs) == FFFTP_SUCCESS)\r
+                                                       {\r
+                                                               saTmpAddr.sin_addr.s_addr = inet_addr(ExtAdrs);\r
+                                                               SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin_port));\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               ReportWSError("listen", WSAGetLastError());\r
+                                               do_closesocket(listen_skt);\r
+                                               listen_skt = INVALID_SOCKET;\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       ReportWSError("getsockname", WSAGetLastError());\r
+                                       do_closesocket(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               ReportWSError("bind", WSAGetLastError());\r
+                               do_closesocket(listen_skt);\r
+                               listen_skt = INVALID_SOCKET;\r
+                       }\r
+\r
+                       if(listen_skt == INVALID_SOCKET)\r
+                               // IPv6対応\r
+//                             SetTaskMsg(MSGJPN030);\r
+                               SetTaskMsg(MSGJPN030, MSGJPN333);\r
+               }\r
+       }\r
+       else\r
+               ReportWSError("socket create", WSAGetLastError());\r
+\r
+       if(listen_skt != INVALID_SOCKET)\r
+       {\r
+#define  UC(b)  (((int)b)&0xff)\r
+               // 同時接続対応\r
+//             if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
+//                             UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
+//                             UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
+               if((command(ctrl_skt,NULL, CancelCheckWork, "PORT %d,%d,%d,%d,%d,%d",\r
+                               UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
+                               UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
+               {\r
+                       // IPv6対応\r
+//                     SetTaskMsg(MSGJPN031);\r
+                       SetTaskMsg(MSGJPN031, MSGJPN333);\r
+                       // UPnP対応\r
+                       if(IsUPnPLoaded() == YES)\r
+                       {\r
+                               if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES)\r
+                                       RemovePortMapping(Port);\r
+                       }\r
+                       do_closesocket(listen_skt);\r
+                       listen_skt = INVALID_SOCKET;\r
+               }\r
+//             else\r
+//                     DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
+       }\r
+\r
+       return(listen_skt);\r
+}\r
+\r
+\r
+SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork)\r
+{\r
+       struct sockaddr_in6 SocksSockAddr;      /* SOCKSサーバのアドレス情報 */\r
+       struct sockaddr_in6 CurSockAddr;                /* 接続先ホストのアドレス情報 */\r
+       SOCKET listen_skt;\r
+       int iLength;\r
+       char *a,*p;\r
+       struct sockaddr_in6 saCtrlAddr;\r
+       struct sockaddr_in6 saTmpAddr;\r
+       SOCKS5REQUEST Socks5Cmd;\r
+       SOCKS5REPLY Socks5Reply;\r
+\r
+       int Len;\r
+       int Fwall;\r
+\r
+       char Adrs[40];\r
+       // UPnP対応\r
+       int Port;\r
+       char ExtAdrs[40];\r
+\r
+       // ソケットにデータを付与\r
+       GetAsyncTableDataIPv6(ctrl_skt, &CurSockAddr, &SocksSockAddr);\r
+\r
+       Fwall = FWALL_NONE;\r
+       if(AskHostFireWall() == YES)\r
+               Fwall = FwallType;\r
+\r
+       if((listen_skt = do_socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP)) != INVALID_SOCKET)\r
+       {\r
+               if((Fwall == FWALL_SOCKS5_NOAUTH) || (Fwall == FWALL_SOCKS5_USER))\r
+               {\r
+                       /*===== SOCKS5を使う =====*/\r
+                       DoPrintf("Use SOCKS5 BIND");\r
+                       if(do_connect(listen_skt, (struct sockaddr *)&SocksSockAddr, sizeof(SocksSockAddr), CancelCheckWork) != SOCKET_ERROR)\r
+                       {\r
+                               if(Socks5SelMethod(listen_skt, CancelCheckWork) == FFFTP_FAIL)\r
+                               {\r
+                                       DoClose(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                                       return(listen_skt);\r
+                               }\r
+\r
+                               Len = Socks5MakeCmdPacketIPv6(&Socks5Cmd, SOCKS5_CMD_BIND, UseIPadrs, (char*)&CurSockAddr.sin6_addr, DomainName, CurSockAddr.sin6_port);\r
+\r
+                               Socks5Reply.Result = -1;\r
+                               // 同時接続対応\r
+//                             if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//                                (Socks5GetCmdReply(listen_skt, &Socks5Reply) != FFFTP_SUCCESS) || \r
+//                                (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               if((SocksSendCmd(listen_skt, &Socks5Cmd, Len, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                                  (Socks5GetCmdReply(listen_skt, &Socks5Reply, CancelCheckWork) != FFFTP_SUCCESS) || \r
+                                  (Socks5Reply.Result != SOCKS5_RES_OK))\r
+                               {\r
+                                       SetTaskMsg(MSGJPN029, Socks5Reply.Result, MSGJPN334);\r
+                                       DoClose(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                               }\r
+\r
+                               // IPv6対応\r
+//                             if(Socks5Reply.AdrsInt == 0)\r
+//                                     Socks5Reply.AdrsInt = SocksSockAddr.sin_addr.s_addr;\r
+\r
+                               // IPv6対応\r
+//                             a = (char *)&Socks5Reply.AdrsInt;\r
+//                             p = (char *)&Socks5Reply.Port;\r
+                               a = (char *)&Socks5Reply._dummy[0];\r
+                               p = (char *)&Socks5Reply._dummy[16];\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       /*===== SOCKSを使わない =====*/\r
+                       DoPrintf("Use normal BIND");\r
+                       saCtrlAddr.sin6_port = htons(0);\r
+                       saCtrlAddr.sin6_family = AF_INET6;\r
+                       memset(&saCtrlAddr.sin6_addr, 0, 16);\r
+                       saCtrlAddr.sin6_flowinfo = 0;\r
+                       saCtrlAddr.sin6_scope_id = 0;\r
+\r
+                       if(bind(listen_skt, (struct sockaddr *)&saCtrlAddr, sizeof(struct sockaddr_in6)) != SOCKET_ERROR)\r
+                       {\r
+                               iLength = sizeof(saCtrlAddr);\r
+                               if(getsockname(listen_skt, (struct sockaddr *)&saCtrlAddr, &iLength) != SOCKET_ERROR)\r
+                               {\r
+                                       if(do_listen(listen_skt, 1) == 0)\r
+                                       {\r
+                                               iLength = sizeof(saTmpAddr);\r
+                                               if(getsockname(ctrl_skt, (struct sockaddr *)&saTmpAddr, &iLength) == SOCKET_ERROR)\r
+                                                       ReportWSError("getsockname", WSAGetLastError());\r
+\r
+                                               a = (char *)&saTmpAddr.sin6_addr;\r
+                                               p = (char *)&saCtrlAddr.sin6_port;\r
+                                               // UPnP対応\r
+                                               if(IsUPnPLoaded() == YES && UPnPEnabled == YES)\r
+                                               {\r
+                                                       if(AddPortMapping(AddressToStringIPv6(Adrs, &saTmpAddr.sin6_addr), ntohs(saCtrlAddr.sin6_port), ExtAdrs) == FFFTP_SUCCESS)\r
+                                                       {\r
+                                                               saTmpAddr.sin6_addr = inet6_addr(ExtAdrs);\r
+                                                               SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin6_port));\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               ReportWSError("listen", WSAGetLastError());\r
+                                               do_closesocket(listen_skt);\r
+                                               listen_skt = INVALID_SOCKET;\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       ReportWSError("getsockname", WSAGetLastError());\r
+                                       do_closesocket(listen_skt);\r
+                                       listen_skt = INVALID_SOCKET;\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               ReportWSError("bind", WSAGetLastError());\r
+                               do_closesocket(listen_skt);\r
+                               listen_skt = INVALID_SOCKET;\r
+                       }\r
+\r
+                       if(listen_skt == INVALID_SOCKET)\r
+                               SetTaskMsg(MSGJPN030, MSGJPN334);\r
+               }\r
+       }\r
+       else\r
+               ReportWSError("socket create", WSAGetLastError());\r
+\r
+       if(listen_skt != INVALID_SOCKET)\r
+       {\r
+#define  UC(b)  (((int)b)&0xff)\r
+               // 同時接続対応\r
+//             if((command(ctrl_skt,NULL, &CancelFlg, "PORT %d,%d,%d,%d,%d,%d",\r
+//                             UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),\r
+//                             UC(p[0]), UC(p[1])) / 100) != FTP_COMPLETE)\r
+               if((command(ctrl_skt,NULL, CancelCheckWork, "EPRT |2|%s|%d|",\r
+                               AddressToStringIPv6(Adrs, a),\r
+                               (UC(p[0]) << 8) | UC(p[1])) / 100) != FTP_COMPLETE)\r
+               {\r
+                       SetTaskMsg(MSGJPN031, MSGJPN334);\r
+                       // UPnP対応\r
+                       if(IsUPnPLoaded() == YES)\r
+                       {\r
+                               if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES)\r
+                                       RemovePortMapping(Port);\r
+                       }\r
+                       do_closesocket(listen_skt);\r
+                       listen_skt = INVALID_SOCKET;\r
+               }\r
+//             else\r
+//                     DoPrintf("Skt=%u : listener %s port %u",listen_skt,inet_ntoa(saCtrlAddr.sin_addr),ntohs(saCtrlAddr.sin_port));\r
+       }\r
+\r
+       return(listen_skt);\r
+}\r
+\r
+\r
+/*----- ホストへ接続処理中かどうかを返す---------------------------------------\r
+*\r
+*      Parameter\r
+*              なし\r
+*\r
+*      Return Value\r
+*              int ステータス\r
+*                      YES/NO\r
+*----------------------------------------------------------------------------*/\r
+\r
+int AskTryingConnect(void)\r
+{\r
+       return(TryConnect);\r
+}\r
+\r
+\r
+#if 0\r
+///*----- ブロッキングコールのフックコールバック --------------------------------\r
+//*\r
+//*    Parameter\r
+//*            なし\r
+//*\r
+//*    Return Value\r
+//*            BOOL FALSE\r
+//*----------------------------------------------------------------------------*/\r
+//\r
+//static BOOL CALLBACK BlkHookFnc(void)\r
+//{\r
+//     BackgrndMessageProc();\r
+//\r
+//     if(CancelFlg == YES)\r
+//     {\r
+//             SetTaskMsg(MSGJPN032);\r
+//             WSACancelBlockingCall();\r
+//             CancelFlg = NO;\r
+//     }\r
+//     return(FALSE);\r
+//}\r
+#endif\r
+\r
+\r
+\r
+/*----- SOCKS5のコマンドパケットを作成する ------------------------------------\r
+*\r
+*      Parameter\r
+*              SOCKS5REQUEST *Packet : パケットを作成するワーク\r
+*              char Cmd : コマンド\r
+*              int ValidIP : IPアドレスを使うかどうか(YES/NO)\r
+*              ulong IP : IPアドレス\r
+*              char *Host : ホスト名\r
+*              ushort Port : ポート\r
+*\r
+*      Return Value\r
+*              int コマンドパケットの長さ\r
+*----------------------------------------------------------------------------*/\r
+\r
+static int Socks5MakeCmdPacket(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, ulong IP, char *Host, ushort Port)\r
+{\r
+       uchar *Pos;\r
+       int Len;\r
+       int TotalLen;\r
+\r
+       Pos = (uchar *)Packet;\r
+       Pos += SOCKS5REQUEST_SIZE;\r
+       TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
+\r
+       Packet->Ver = SOCKS5_VER;\r
+       Packet->Cmd = Cmd;\r
+       Packet->Rsv = 0;\r
+       if(ValidIP == YES)\r
+       {\r
+               /* IPアドレスを指定 */\r
+               Packet->Type = SOCKS5_ADRS_IPV4;\r
+               *((ulong *)Pos) = IP;\r
+               Pos += 4;\r
+               TotalLen += 4;\r
+       }\r
+       else\r
+       {\r
+               /* ホスト名を指定 */\r
+               Packet->Type = SOCKS5_ADRS_NAME;\r
+               Len = strlen(Host);\r
+               *Pos++ = Len;\r
+               strcpy(Pos, Host);\r
+               Pos += Len;\r
+               TotalLen += Len + 1;\r
+       }\r
+       *((ushort *)Pos) = Port;\r
+\r
+       return(TotalLen);\r
+}\r
+\r
+\r
+// IPv6対応\r
+static int Socks5MakeCmdPacketIPv6(SOCKS5REQUEST *Packet, char Cmd, int ValidIP, char *IP, char *Host, ushort Port)\r
+{\r
+       uchar *Pos;\r
+       int Len;\r
+       int TotalLen;\r
+\r
+       Pos = (uchar *)Packet;\r
+       Pos += SOCKS5REQUEST_SIZE;\r
+       TotalLen = SOCKS5REQUEST_SIZE + 2;      /* +2はポートの分 */\r
+\r
+       Packet->Ver = SOCKS5_VER;\r
+       Packet->Cmd = Cmd;\r
+       Packet->Rsv = 0;\r
+       if(ValidIP == YES)\r
+       {\r
+               /* IPアドレスを指定 */\r
+               Packet->Type = SOCKS5_ADRS_IPV6;\r
+               memcpy(Pos, IP, 16);\r
+               Pos += 16;\r
+               TotalLen += 16;\r
+       }\r
+       else\r
+       {\r
+               /* ホスト名を指定 */\r
+               Packet->Type = SOCKS5_ADRS_NAME;\r
+               Len = strlen(Host);\r
+               *Pos++ = Len;\r
+               strcpy(Pos, Host);\r
+               Pos += Len;\r
+               TotalLen += Len + 1;\r
+       }\r
+       *((ushort *)Pos) = Port;\r
+\r
+       return(TotalLen);\r
+}\r
+\r
+\r
+/*----- SOCKSのコマンドを送る -------------------------------------------------\r
+*\r
+*      Parameter\r
+*              SOCKET Socket : ソケット\r
+*              void *Data : 送るデータ\r
+*              int Size : サイズ\r
+*\r
+*      Return Value\r
+*              int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
+*----------------------------------------------------------------------------*/\r
+\r
+static int SocksSendCmd(SOCKET Socket, void *Data, int Size, int *CancelCheckWork)\r
+{\r
+       int Ret;\r
+\r
+       Ret = SendData(Socket, (char *)Data, Size, 0, CancelCheckWork);\r
+\r
+       if(Ret != FFFTP_SUCCESS)\r
+               SetTaskMsg(MSGJPN033, *((short *)Data));\r
+\r
+       return(Ret);\r
+}\r
+\r
+\r
+/*----- SOCKS5のコマンドに対するリプライパケットを受信する --------------------\r
+*\r
+*      Parameter\r
+*              SOCKET Socket : ソケット\r
+*              SOCKS5REPLY *Packet : パケット\r
+*\r
+*      Return Value\r
+*              int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
+*----------------------------------------------------------------------------*/\r
+\r
+// 同時接続対応\r
+//static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet)\r
+static int Socks5GetCmdReply(SOCKET Socket, SOCKS5REPLY *Packet, int *CancelCheckWork)\r
+{\r
+       uchar *Pos;\r
+       int Len;\r
+       int Ret;\r
+\r
+       Pos = (uchar *)Packet;\r
+       Pos += SOCKS5REPLY_SIZE;\r
+\r
+       // 同時接続対応\r
+//     if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, &CancelFlg)) == FFFTP_SUCCESS)\r
+       if((Ret = ReadNchar(Socket, (char *)Packet, SOCKS5REPLY_SIZE, CancelCheckWork)) == FFFTP_SUCCESS)\r
+       {\r
+               if(Packet->Type == SOCKS5_ADRS_IPV4)\r
+                       Len = 4 + 2;\r
+               else if(Packet->Type == SOCKS5_ADRS_IPV6)\r
+                       Len = 16 + 2;\r
+               else\r
+               {\r
+                       // 同時接続対応\r
+//                     if((Ret = ReadNchar(Socket, (char *)Pos, 1, &CancelFlg)) == FFFTP_SUCCESS)\r
+                       if((Ret = ReadNchar(Socket, (char *)Pos, 1, CancelCheckWork)) == FFFTP_SUCCESS)\r
+                       {\r
+                               Len = *Pos + 2;\r
+                               Pos++;\r
+                       }\r
+               }\r
+\r
+               if(Ret == FFFTP_SUCCESS)\r
+                       // 同時接続対応\r
+//                     Ret = ReadNchar(Socket, (char *)Pos, Len, &CancelFlg);\r
+                       Ret = ReadNchar(Socket, (char *)Pos, Len, CancelCheckWork);\r
+       }\r
+\r
+       if(Ret != FFFTP_SUCCESS)\r
+               SetTaskMsg(MSGJPN034);\r
+\r
+       return(Ret);\r
+}\r
+\r
+\r
+/*----- SOCKS4のコマンドに対するリプライパケットを受信する --------------------\r
+*\r
+*      Parameter\r
+*              SOCKET Socket : ソケット\r
+*              SOCKS5REPLY *Packet : パケット\r
+*\r
+*      Return Value\r
+*              int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
+*----------------------------------------------------------------------------*/\r
+\r
+// 同時接続対応\r
+//static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet)\r
+static int Socks4GetCmdReply(SOCKET Socket, SOCKS4REPLY *Packet, int *CancelCheckWork)\r
+{\r
+       int Ret;\r
+\r
+       // 同時接続対応\r
+//     Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, &CancelFlg);\r
+       Ret = ReadNchar(Socket, (char *)Packet, SOCKS4REPLY_SIZE, CancelCheckWork);\r
+\r
+       if(Ret != FFFTP_SUCCESS)\r
+               DoPrintf(MSGJPN035);\r
+\r
+       return(Ret);\r
+}\r
+\r
+\r
+/*----- SOCKS5の認証を行う ----------------------------------------------------\r
+*\r
+*      Parameter\r
+*              SOCKET Socket : ソケット\r
+*\r
+*      Return Value\r
+*              int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
+*----------------------------------------------------------------------------*/\r
+\r
+static int Socks5SelMethod(SOCKET Socket, int *CancelCheckWork)\r
+{\r
+       int Ret;\r
+       SOCKS5METHODREQUEST Socks5Method;\r
+       SOCKS5METHODREPLY Socks5MethodReply;\r
+       SOCKS5USERPASSSTATUS Socks5Status;\r
+       char Buf[USER_NAME_LEN + PASSWORD_LEN + 4];\r
+       int Len;\r
+       int Len2;\r
+\r
+       Ret = FFFTP_SUCCESS;\r
+       Socks5Method.Ver = SOCKS5_VER;\r
+       Socks5Method.Num = 1;\r
+       if(FwallType == FWALL_SOCKS5_NOAUTH)\r
+               Socks5Method.Methods[0] = SOCKS5_AUTH_NONE;\r
+       else\r
+               Socks5Method.Methods[0] = SOCKS5_AUTH_USER;\r
+\r
+       // 同時接続対応\r
+//     if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//        (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, &CancelFlg) != FFFTP_SUCCESS) ||\r
+//        (Socks5MethodReply.Method == (uchar)0xFF))\r
+       if((SocksSendCmd(Socket, &Socks5Method, SOCKS5METHODREQUEST_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+          (ReadNchar(Socket, (char *)&Socks5MethodReply, SOCKS5METHODREPLY_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+          (Socks5MethodReply.Method == (uchar)0xFF))\r
+       {\r
+               SetTaskMsg(MSGJPN036);\r
+               Ret = FFFTP_FAIL;\r
+       }\r
+       else if(Socks5MethodReply.Method == SOCKS5_AUTH_USER)\r
+       {\r
+               DoPrintf("SOCKS5 User/Pass Authentication");\r
+               Buf[0] = SOCKS5_USERAUTH_VER;\r
+               Len = strlen(FwallUser);\r
+               Len2 = strlen(FwallPass);\r
+               Buf[1] = Len;\r
+               strcpy(Buf+2, FwallUser);\r
+               Buf[2 + Len] = Len2;\r
+               strcpy(Buf+3+Len, FwallPass);\r
+\r
+               // 同時接続対応\r
+//             if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+//                (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, &CancelFlg) != FFFTP_SUCCESS) ||\r
+//                (Socks5Status.Status != 0))\r
+               if((SocksSendCmd(Socket, &Buf, Len+Len2+3, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                  (ReadNchar(Socket, (char *)&Socks5Status, SOCKS5USERPASSSTATUS_SIZE, CancelCheckWork) != FFFTP_SUCCESS) ||\r
+                  (Socks5Status.Status != 0))\r
+               {\r
+                       SetTaskMsg(MSGJPN037);\r
+                       Ret = FFFTP_FAIL;\r
+               }\r
+       }\r
+       else\r
+               DoPrintf("SOCKS5 No Authentication");\r
+\r
+       return(Ret);\r
+}\r
+\r
+\r
+/*----- SOCKSのBINDの第2リプライメッセージを受け取る -------------------------\r
+*\r
+*      Parameter\r
+*              SOCKET Socket : ソケット\r
+*              SOCKET *Data : データソケットを返すワーク\r
+*\r
+*      Return Value\r
+*              int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
+*----------------------------------------------------------------------------*/\r
+\r
+// 同時接続対応\r
+//int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data)\r
+int SocksGet2ndBindReply(SOCKET Socket, SOCKET *Data, int *CancelCheckWork)\r
+{\r
+       int Ret;\r
+       char Buf[300];\r
+\r
+       Ret = FFFTP_FAIL;\r
+       if((AskHostFireWall() == YES) && (FwallType == FWALL_SOCKS4))\r
+       {\r
+               // 同時接続対応\r
+//             Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf);\r
+               Socks4GetCmdReply(Socket, (SOCKS4REPLY *)Buf, CancelCheckWork);\r
+               *Data = Socket;\r
+               Ret = FFFTP_SUCCESS;\r
+       }\r
+       else if((AskHostFireWall() == YES) &&\r
+                       ((FwallType == FWALL_SOCKS5_NOAUTH) || (FwallType == FWALL_SOCKS5_USER)))\r
+       {\r
+               // 同時接続対応\r
+//             Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf);\r
+               Socks5GetCmdReply(Socket, (SOCKS5REPLY *)Buf, CancelCheckWork);\r
+               *Data = Socket;\r
+               Ret = FFFTP_SUCCESS;\r
+       }\r
+       return(Ret);\r
+}\r
+\r
+\r
+\r
+// 暗号化通信対応\r
+int AskCryptMode(void)\r
+{\r
+       return(CurHost.CryptMode);\r
+}\r
+\r
+int AskUseNoEncryption(void)\r
+{\r
+       return(CurHost.UseNoEncryption);\r
+}\r
+\r
+int AskUseFTPES(void)\r
+{\r
+       return(CurHost.UseFTPES);\r
+}\r
+\r
+int AskUseFTPIS(void)\r
+{\r
+       return(CurHost.UseFTPIS);\r
+}\r
+\r
+int AskUseSFTP(void)\r
+{\r
+       return(CurHost.UseSFTP);\r
+}\r
+\r
+char *AskPrivateKey(void)\r
+{\r
+       return(CurHost.PrivateKey);\r
+}\r
+\r
+// 同時接続対応\r
+int AskMaxThreadCount(void)\r
+{\r
+       return(CurHost.MaxThreadCount);\r
+}\r
+\r
+int AskReuseCmdSkt(void)\r
+{\r
+       return(CurHost.ReuseCmdSkt);\r
+}\r
+\r
+// FEAT対応\r
+int AskHostFeature(void)\r
+{\r
+       return(CurHost.Feature);\r
+}\r
+\r
+// MLSD対応\r
+int AskUseMLSD(void)\r
+{\r
+       return(CurHost.UseMLSD);\r
+}\r
+\r
+// IPv6対応\r
+int AskCurNetType(void)\r
+{\r
+       return(CurHost.CurNetType);\r
+}\r
+\r
+// 自動切断対策\r
+int AskNoopInterval(void)\r
+{\r
+       return(CurHost.NoopInterval);\r
+}\r
+\r
+// 再転送対応\r
+int AskTransferErrorMode(void)\r
+{\r
+       return(CurHost.TransferErrorMode);\r
+}\r
+\r
+int AskTransferErrorNotify(void)\r
+{\r
+       return(CurHost.TransferErrorNotify);\r
+}\r
+\r
+// セッションあたりの転送量制限対策\r
+int AskErrorReconnect(void)\r
+{\r
+       return(CurHost.TransferErrorReconnect);\r
+}\r
+\r
+// ホスト側の設定ミス対策\r
+int AskNoPasvAdrs(void)\r
+{\r
+       return(CurHost.NoPasvAdrs);\r
+}\r
+\r