Fix bugs of simultaneous connection.
Add support for reusing control connection.
EDITTEXT HSET_THREAD_COUNT,72,8,17,12,ES_AUTOHSCROLL | ES_NUMBER\r
CONTROL "Spin1",HSET_THREAD_COUNT_SPN,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,89,7,9,14\r
LTEXT "(1\81`4)",-1,102,10,31,8\r
+ CONTROL "\83\81\83C\83\93\83E\83B\83\93\83h\83E\82Ì\83\\83P\83b\83g\82ð\8dÄ\97\98\97p",HSET_REUSE_SOCKET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,27,131,10\r
END\r
\r
\r
#define HSET_THREAD_COUNT 1204\r
#define HSET_THREAD_COUNT_SPN 1205\r
#define HSET_UTF8BOM_CNV 1206\r
+#define HSET_REUSE_SOCKET 1207\r
#define MENU_END 40001\r
#define MENU_EXIT 40001\r
#define MENU_CONNECT 40003\r
#ifndef APSTUDIO_READONLY_SYMBOLS\r
#define _APS_NEXT_RESOURCE_VALUE 191\r
#define _APS_NEXT_COMMAND_VALUE 40176\r
-#define _APS_NEXT_CONTROL_VALUE 1207\r
+#define _APS_NEXT_CONTROL_VALUE 1208\r
#define _APS_NEXT_SYMED_VALUE 101\r
#endif\r
#endif\r
EDITTEXT HSET_THREAD_COUNT,72,8,17,12,ES_AUTOHSCROLL | ES_NUMBER\r
CONTROL "Spin1",HSET_THREAD_COUNT_SPN,"msctls_updown32",UDS_SETBUDDYINT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,89,7,9,14\r
LTEXT "(1 to 4 threads)",-1,102,10,53,8\r
+ CONTROL "Reuse socket of the main window",HSET_REUSE_SOCKET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,27,131,10\r
END\r
\r
\r
#define HSET_THREAD_COUNT 1204\r
#define HSET_THREAD_COUNT_SPN 1205\r
#define HSET_UTF8BOM_CNV 1206\r
+#define HSET_REUSE_SOCKET 1207\r
#define MENU_END 40001\r
#define MENU_EXIT 40001\r
#define MENU_CONNECT 40003\r
#ifndef APSTUDIO_READONLY_SYMBOLS\r
#define _APS_NEXT_RESOURCE_VALUE 191\r
#define _APS_NEXT_COMMAND_VALUE 40176\r
-#define _APS_NEXT_CONTROL_VALUE 1207\r
+#define _APS_NEXT_CONTROL_VALUE 1208\r
#define _APS_NEXT_SYMED_VALUE 101\r
#endif\r
#endif\r
char PrivateKey[PRIVATE_KEY_LEN+1]; /* テキスト形式の秘密鍵 */\r
// 同時接続対応\r
int MaxThreadCount; /* 同時接続数 */\r
+ int ReuseCmdSkt; /* メインウィンドウのソケットを再利用する (YES/NO) */\r
// FEAT対応\r
int Feature; /* 利用可能な機能のフラグ (FEATURE_xxx) */\r
// MLSD対応\r
char PrivateKey[PRIVATE_KEY_LEN+1]; /* テキスト形式の秘密鍵 */\r
// 同時接続対応\r
int MaxThreadCount; /* 同時接続数 */\r
+ int ReuseCmdSkt; /* メインウィンドウのソケットを再利用する (YES/NO) */\r
// MLSD対応\r
int UseMLSD; /* "MLSD"コマンドを使用する */\r
// IPv6対応\r
char *AskPrivateKey(void);\r
// 同時接続対応\r
int AskMaxThreadCount(void);\r
+int AskReuseCmdSkt(void);\r
// FEAT対応\r
int AskHostFeature(void);\r
// MLSD対応\r
int Sts;\r
\r
\r
- // 同時接続対応\r
-// if(CmdCtrlSocket != TrnCtrlSocket)\r
- if(CmdCtrlSocket != TrnCtrlSocket && TrnCtrlSocket != INVALID_SOCKET)\r
+ if(CmdCtrlSocket != TrnCtrlSocket)\r
do_closesocket(TrnCtrlSocket);\r
TrnCtrlSocket = INVALID_SOCKET;\r
\r
//SetTaskMsg("############### SktShareProh");\r
\r
// 同時接続対応\r
- // 転送スレッドがソケットを各自で用意\r
- // TrnCtrlSocketはメインスレッド以外から使用されない\r
// CmdCtrlSocket = INVALID_SOCKET;\r
// ReConnectSkt(&CmdCtrlSocket);\r
+ if(CurHost.ReuseCmdSkt == YES)\r
+ {\r
+ CmdCtrlSocket = INVALID_SOCKET;\r
+ ReConnectSkt(&CmdCtrlSocket);\r
+ }\r
}\r
return;\r
}\r
int Sts;\r
\r
Sts = YES;\r
+ // 同時接続対応\r
// if(CmdCtrlSocket == TrnCtrlSocket)\r
-// Sts = NO;\r
+ if(CmdCtrlSocket == TrnCtrlSocket || TrnCtrlSocket == INVALID_SOCKET)\r
+ Sts = NO;\r
\r
return(Sts);\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
{\r
DisableUserOpe();\r
\r
- // 同時接続対応\r
- SktShareProh();\r
-\r
ExistNotify = YES;\r
// KeepTransferDialog(YES);\r
\r
{\r
DisableUserOpe();\r
\r
- // 同時接続対応\r
- SktShareProh();\r
-\r
ExistNotify = YES;\r
// KeepTransferDialog(YES);\r
\r
{\r
DisableUserOpe();\r
\r
- // 同時接続対応\r
- SktShareProh();\r
-\r
Base = NULL;\r
\r
if(Notify == YES)\r
{\r
DisableUserOpe();\r
\r
- // 同時接続対応\r
- SktShareProh();\r
-\r
// ローカル側で選ばれているファイルをFileListBaseに登録\r
FileListBase = NULL;\r
MakeSelectedFileList(WIN_LOCAL, YES, All, &FileListBase, &CancelFlg);\r
{\r
DisableUserOpe();\r
\r
- // 同時接続対応\r
- SktShareProh();\r
-\r
// ローカル側で選ばれているファイルをFileListBaseに登録\r
FileListBase = NULL;\r
MakeDroppedFileList(wParam, Cur, &FileListBase);\r
{\r
DisableUserOpe();\r
\r
- // 同時接続対応\r
- SktShareProh();\r
-\r
Base = NULL;\r
\r
if(Notify == YES)\r
#include <string.h>\r
#include <mbstring.h>\r
#include <time.h>\r
-#include <winsock.h>\r
+// IPv6対応\r
+//#include <winsock.h>\r
+#include <winsock2.h>\r
#include <windowsx.h>\r
#include <commctrl.h>\r
#include <process.h>\r
free(Pos);\r
}\r
NewCmdSkt = AskCmdCtrlSkt();\r
- if(TransPacketBase && NewCmdSkt != INVALID_SOCKET && ThreadCount < AskMaxThreadCount())\r
+ if(AskReuseCmdSkt() == YES && ThreadCount == 0)\r
{\r
- if(TrnSkt == INVALID_SOCKET || NewCmdSkt != CmdSkt)\r
+ if(TransPacketBase && ThreadCount < AskMaxThreadCount())\r
+ TrnSkt = AskTrnCtrlSkt();\r
+ }\r
+ else\r
+ {\r
+ if(TransPacketBase && NewCmdSkt != INVALID_SOCKET && ThreadCount < AskMaxThreadCount())\r
{\r
- ReleaseMutex(hListAccMutex);\r
- ReConnectTrnSkt(&TrnSkt, &Canceled[ThreadCount]);\r
- // 同時ログイン数制限に引っかかった可能性あり\r
- // 負荷を下げるためにしばらく待機\r
- if(TrnSkt == INVALID_SOCKET)\r
+ if(TrnSkt == INVALID_SOCKET || NewCmdSkt != CmdSkt)\r
{\r
- i = 10000;\r
- while(NewCmdSkt != CmdSkt && i > 0)\r
+ ReleaseMutex(hListAccMutex);\r
+ ReConnectTrnSkt(&TrnSkt, &Canceled[ThreadCount]);\r
+ // 同時ログイン数制限に引っかかった可能性あり\r
+ // 負荷を下げるためにしばらく待機\r
+ if(TrnSkt == INVALID_SOCKET)\r
+ {\r
+ i = 10000;\r
+ while(NewCmdSkt != CmdSkt && i > 0)\r
+ {\r
+ BackgrndMessageProc();\r
+ Sleep(1);\r
+ i--;\r
+ }\r
+ }\r
+// WaitForSingleObject(hListAccMutex, INFINITE);\r
+ while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
{\r
BackgrndMessageProc();\r
Sleep(1);\r
- i--;\r
}\r
}\r
-// WaitForSingleObject(hListAccMutex, INFINITE);\r
- while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
- {\r
- BackgrndMessageProc();\r
- Sleep(1);\r
- }\r
}\r
- }\r
- else\r
- {\r
- if(TrnSkt != INVALID_SOCKET)\r
+ else\r
{\r
- ReleaseMutex(hListAccMutex);\r
- DoClose(TrnSkt);\r
- TrnSkt = INVALID_SOCKET;\r
-// WaitForSingleObject(hListAccMutex, INFINITE);\r
- while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+ if(TrnSkt != INVALID_SOCKET)\r
{\r
- BackgrndMessageProc();\r
- Sleep(1);\r
+ ReleaseMutex(hListAccMutex);\r
+ SendData(TrnSkt, "QUIT\r\n", 6, 0, &Canceled[ThreadCount]);\r
+ DoClose(TrnSkt);\r
+ TrnSkt = INVALID_SOCKET;\r
+// WaitForSingleObject(hListAccMutex, INFINITE);\r
+ while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+ {\r
+ BackgrndMessageProc();\r
+ Sleep(1);\r
+ }\r
}\r
}\r
}\r
// else if(strcmp(TransPacketBase->Cmd, "SETCUR") == 0)\r
else if(strcmp(Pos->Cmd, "SETCUR") == 0)\r
{\r
- if(AskShareProh() == YES)\r
+// if(AskShareProh() == YES)\r
+ if(AskReuseCmdSkt() == NO || AskShareProh() == YES)\r
{\r
// if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
if(strcmp(CurDir[Pos->ThreadCount], Pos->RemoteFile) != 0)\r
// else if(strcmp(TransPacketBase->Cmd, "BACKCUR") == 0)\r
else if(strcmp(Pos->Cmd, "BACKCUR") == 0)\r
{\r
- if(AskShareProh() == NO)\r
+// if(AskShareProh() == NO)\r
+ if(AskReuseCmdSkt() == YES && AskShareProh() == NO)\r
{\r
// if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
// CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile);\r
Sleep(100);\r
}\r
}\r
- if(TrnSkt != INVALID_SOCKET)\r
- DoClose(TrnSkt);\r
+ if(AskReuseCmdSkt() == NO || ThreadCount > 0)\r
+ {\r
+ if(TrnSkt != INVALID_SOCKET)\r
+ {\r
+ SendData(TrnSkt, "QUIT\r\n", 6, 0, &Canceled[ThreadCount]);\r
+ DoClose(TrnSkt);\r
+ }\r
+ }\r
return 0;\r
}\r
\r
}\r
\r
\r
+// IPv6対応\r
+static int GetAdrsAndPortIPv6(char *Str, char *Adrs, int *Port, int Max, short *Family)\r
+{\r
+ char *Pos;\r
+ char *Btm;\r
+ int Sts;\r
+\r
+ Sts = FFFTP_FAIL;\r
+\r
+ Pos = strchr(Str, '|');\r
+ if(Pos != NULL)\r
+ {\r
+ Pos++;\r
+ Btm = strchr(Pos, '|');\r
+ if(Btm != NULL)\r
+ {\r
+ switch(atoi(Pos))\r
+ {\r
+ case 1:\r
+ *Family = AF_INET;\r
+ break;\r
+ case 2:\r
+ *Family = AF_INET6;\r
+ break;\r
+ }\r
+ Pos = Btm + 1;\r
+ Btm = strchr(Pos, '|');\r
+ if(Btm != NULL)\r
+ {\r
+ if((Btm - Pos) <= Max)\r
+ {\r
+ if((Btm - Pos) > 0)\r
+ {\r
+ strncpy(Adrs, Pos, Btm - Pos);\r
+ *(Adrs + (Btm - Pos)) = NUL;\r
+ }\r
+\r
+ Pos = Btm + 1;\r
+ Btm = strchr(Pos, '|');\r
+ if(Btm != NULL)\r
+ {\r
+ Btm++;\r
+ *Port = atoi(Pos);\r
+ Sts = FFFTP_SUCCESS;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return(Sts);\r
+}\r
+\r
+\r
/*----- Windowsのスペシャルデバイスかどうかを返す -----------------------------\r
*\r
* Parameter\r
strcpy(New->PrivateKey, Host->PrivateKey);\r
// 同時接続対応\r
New->MaxThreadCount = Host->MaxThreadCount;\r
+ New->ReuseCmdSkt = Host->ReuseCmdSkt;\r
// MLSD対応\r
New->UseMLSD = Host->UseMLSD;\r
// IPv6対応\r
strcpy(Host->PrivateKey, Hist->PrivateKey);\r
// 同時接続対応\r
Host->MaxThreadCount = Hist->MaxThreadCount;\r
+ Host->ReuseCmdSkt = Hist->ReuseCmdSkt;\r
// MLSD対応\r
Host->UseMLSD = Hist->UseMLSD;\r
// IPv6対応\r
Set->UseSFTP = Pos->Set.UseSFTP;\r
// 同時接続対応\r
Set->MaxThreadCount = Pos->Set.MaxThreadCount;\r
+ Set->ReuseCmdSkt = Pos->Set.ReuseCmdSkt;\r
// MLSD対応\r
Set->UseMLSD = Pos->Set.UseMLSD;\r
// IPv6対応\r
strcpy(Set->PrivateKey, "");\r
// 同時接続対応\r
Set->MaxThreadCount = 1;\r
+ Set->ReuseCmdSkt = NO;\r
// MLSD対応\r
Set->Feature = 0;\r
Set->UseMLSD = YES;\r
SendDlgItemMessage(hDlg, HSET_THREAD_COUNT, EM_LIMITTEXT, (WPARAM)1, 0);\r
SetDecimalText(hDlg, HSET_THREAD_COUNT, TmpHost.MaxThreadCount);\r
SendDlgItemMessage(hDlg, HSET_THREAD_COUNT_SPN, UDM_SETRANGE, 0, (LPARAM)MAKELONG(MAX_DATA_CONNECTION, 1));\r
+ SendDlgItemMessage(hDlg, HSET_REUSE_SOCKET, BM_SETCHECK, TmpHost.ReuseCmdSkt, 0);\r
return(TRUE);\r
\r
case WM_NOTIFY:\r
case PSN_APPLY :\r
TmpHost.MaxThreadCount = GetDecimalText(hDlg, HSET_THREAD_COUNT);\r
CheckRange2(&TmpHost.MaxThreadCount, MAX_DATA_CONNECTION, 1);\r
+ TmpHost.ReuseCmdSkt = SendDlgItemMessage(hDlg, HSET_REUSE_SOCKET, BM_GETCHECK, 0, 0);\r
Apply = YES;\r
break;\r
\r
int MirDownDelNotify = YES; \r
int FolderAttr = NO;\r
int FolderAttrNum = 777;\r
-// 同時接続対応\r
-int MaxThreadCount = 1;\r
// 暗号化通信対応\r
BYTE CertificateCacheHash[MAX_CERT_CACHE_HASH][20];\r
\r
SaveStr(hKey5, "PKey", Str, DefaultHist.PrivateKey);\r
// 同時接続対応\r
SaveIntNum(hKey5, "ThreadCount", Hist.MaxThreadCount, DefaultHist.MaxThreadCount);\r
+ SaveIntNum(hKey5, "ReuseCmdSkt", Hist.ReuseCmdSkt, DefaultHist.ReuseCmdSkt);\r
// MLSD対応\r
SaveIntNum(hKey5, "MLSD", Hist.UseMLSD, DefaultHist.UseMLSD);\r
// IPv6対応\r
SaveStr(hKey5, "PKey", Str, DefaultHost.PrivateKey);\r
// 同時接続対応\r
SaveIntNum(hKey5, "ThreadCount", Host.MaxThreadCount, DefaultHost.MaxThreadCount);\r
+ SaveIntNum(hKey5, "ReuseCmdSkt", Host.ReuseCmdSkt, DefaultHost.ReuseCmdSkt);\r
// MLSD対応\r
SaveIntNum(hKey5, "MLSD", Host.UseMLSD, DefaultHost.UseMLSD);\r
// IPv6対応\r
DecodePassword(Str, Hist.PrivateKey);\r
// 同時接続対応\r
ReadIntValueFromReg(hKey5, "ThreadCount", &Hist.MaxThreadCount);\r
+ ReadIntValueFromReg(hKey5, "ReuseCmdSkt", &Hist.ReuseCmdSkt);\r
// MLSD対応\r
ReadIntValueFromReg(hKey5, "MLSD", &Hist.UseMLSD);\r
// IPv6対応\r
DecodePassword(Str, Host.PrivateKey);\r
// 同時接続対応\r
ReadIntValueFromReg(hKey5, "ThreadCount", &Host.MaxThreadCount);\r
+ ReadIntValueFromReg(hKey5, "ReuseCmdSkt", &Host.ReuseCmdSkt);\r
// MLSD対応\r
ReadIntValueFromReg(hKey5, "MLSD", &Host.UseMLSD);\r
// IPv6対応\r
/============================================================================*/\r
\r
#define STRICT\r
+// IPv6対応\r
+#include <ws2tcpip.h>\r
#include <windows.h>\r
#include <stdio.h>\r
#include <stdlib.h>\r
\r
\r
\r
-#define FD_CONNECT_BIT 0x0001\r
-#define FD_CLOSE_BIT 0x0002\r
-#define FD_ACCEPT_BIT 0x0004\r
-#define FD_READ_BIT 0x0008\r
-#define FD_WRITE_BIT 0x0010\r
+// Winsock2で定義される定数と名前が重複し値が異なるため使用不可\r
+//#define FD_CONNECT_BIT 0x0001\r
+//#define FD_CLOSE_BIT 0x0002\r
+//#define FD_ACCEPT_BIT 0x0004\r
+//#define FD_READ_BIT 0x0008\r
+//#define FD_WRITE_BIT 0x0010\r
\r
\r
\r
// 念のためテーブルを増量\r
//#define MAX_SIGNAL_ENTRY 10\r
//#define MAX_SIGNAL_ENTRY_DBASE 5\r
-#define MAX_SIGNAL_ENTRY 100\r
-#define MAX_SIGNAL_ENTRY_DBASE 50\r
+#define MAX_SIGNAL_ENTRY 16\r
+#define MAX_SIGNAL_ENTRY_DBASE 16\r
\r
\r
\r
static int UnRegistAsyncTableDbase(HANDLE Async);\r
// UTF-8対応\r
static HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen);\r
+// IPv6対応\r
+static HANDLE WSAAsyncGetHostByNameIPv6M(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family);\r
\r
\r
/*===== 外部参照 =====*/\r
*Error = Signal[Pos].Error;\r
if(Signal[Pos].Error != 0)\r
Sts = YES;\r
- if((Mask & FD_CONNECT_BIT) && (Signal[Pos].FdConnect != 0))\r
+ if((Mask & FD_CONNECT) && (Signal[Pos].FdConnect != 0))\r
{\r
Sts = YES;\r
#if DBG_MSG\r
DoPrintf("### Ask: connect (Sts=%d, Error=%d)", Sts, *Error);\r
#endif\r
}\r
- if((Mask & FD_CLOSE_BIT) && (Signal[Pos].FdClose != 0))\r
-// if(Mask & FD_CLOSE_BIT)\r
+ if((Mask & FD_CLOSE) && (Signal[Pos].FdClose != 0))\r
+// if(Mask & FD_CLOSE)\r
{\r
Sts = YES;\r
#if DBG_MSG\r
DoPrintf("### Ask: close (Sts=%d, Error=%d)", Sts, *Error);\r
#endif\r
}\r
- if((Mask & FD_ACCEPT_BIT) && (Signal[Pos].FdAccept != 0))\r
+ if((Mask & FD_ACCEPT) && (Signal[Pos].FdAccept != 0))\r
{\r
Signal[Pos].FdAccept = 0;\r
Sts = YES;\r
DoPrintf("### Ask: accept (Sts=%d, Error=%d)", Sts, *Error);\r
#endif\r
}\r
- if((Mask & FD_READ_BIT) && (Signal[Pos].FdRead != 0))\r
+ if((Mask & FD_READ) && (Signal[Pos].FdRead != 0))\r
{\r
Signal[Pos].FdRead = 0;\r
Sts = YES;\r
DoPrintf("### Ask: read (Sts=%d, Error=%d)", Sts, *Error);\r
#endif\r
}\r
- if((Mask & FD_WRITE_BIT) && (Signal[Pos].FdWrite != 0))\r
+ if((Mask & FD_WRITE) && (Signal[Pos].FdWrite != 0))\r
{\r
Signal[Pos].FdWrite = 0;\r
Sts = YES;\r
\r
if(Pos == MAX_SIGNAL_ENTRY)\r
{\r
- if(Mask & FD_CLOSE_BIT)\r
+ if(Mask & FD_CLOSE)\r
{\r
Sts = YES;\r
}\r
\r
// UTF-8対応\r
// hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
- hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+ // IPv6対応\r
+// hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+ hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET);\r
if(hAsync != NULL)\r
{\r
RegistAsyncTableDbase(hAsync);\r
if(Ret == SOCKET_ERROR)\r
{\r
Error = 0;\r
- while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE_BIT) != YES))\r
+ while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE) != YES))\r
{\r
Sleep(1);\r
if(BackgrndMessageProc() == YES)\r
#if DBG_MSG\r
DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");\r
#endif\r
- Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
+ // 高速化のためFD_READとFD_WRITEを使用しない\r
+// Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
+ Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT);\r
if(Ret != SOCKET_ERROR)\r
{\r
Ret = connect(s, name, namelen);\r
do\r
{\r
Error = 0;\r
- while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT_BIT) != YES))\r
+ while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT) != YES))\r
{\r
Sleep(1);\r
if(BackgrndMessageProc() == YES)\r
Ret2 = INVALID_SOCKET;\r
Error = 0;\r
\r
- while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT_BIT) != YES))\r
+ while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT) != YES))\r
{\r
- if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
+ if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
{\r
Error = 1;\r
break;\r
\r
// FTPS対応\r
// OpenSSLでは受信確認はFD_READが複数回受信される可能性がある\r
-// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES))\r
- while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES))\r
- {\r
- if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
- {\r
- Ret = 0;\r
- break;\r
- }\r
- Sleep(1);\r
- if(BackgrndMessageProc() == YES)\r
- *CancelCheckWork = YES;\r
- else if(TimeOut != 0)\r
- {\r
- time(&ElapseTime);\r
- ElapseTime -= StartTime;\r
- if(ElapseTime >= TimeOut)\r
- {\r
- DoPrintf("do_recv timed out");\r
- *TimeOutErr = YES;\r
- *CancelCheckWork = YES;\r
- }\r
- }\r
- }\r
+// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ) != YES))\r
+ // 短時間にFD_READが2回以上通知される対策\r
+// while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ) != YES))\r
+// {\r
+// if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
+// {\r
+// Ret = 0;\r
+// break;\r
+// }\r
+// Sleep(1);\r
+// if(BackgrndMessageProc() == YES)\r
+// *CancelCheckWork = YES;\r
+// else if(TimeOut != 0)\r
+// {\r
+// time(&ElapseTime);\r
+// ElapseTime -= StartTime;\r
+// if(ElapseTime >= TimeOut)\r
+// {\r
+// DoPrintf("do_recv timed out");\r
+// *TimeOutErr = YES;\r
+// *CancelCheckWork = YES;\r
+// }\r
+// }\r
+// }\r
\r
if(/*(Ret != 0) && */(Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO))\r
{\r
\r
// FTPS対応\r
// 送信バッファの空き確認には影響しないが念のため\r
-// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))\r
+// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE) != YES))\r
// Windows 2000でFD_WRITEが通知されないことがあるバグ修正\r
-// while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))\r
+// while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE) != YES))\r
// {\r
-// if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
+// if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
// {\r
// Error = 1;\r
// break;\r
int Error;\r
while((len = recvS(s, buf, sizeof(buf), MSG_PEEK)) >= 0)\r
{\r
- AskAsyncDone(s, &Error, FD_READ_BIT);\r
+ AskAsyncDone(s, &Error, FD_READ);\r
recvS(s, buf, len, 0);\r
}\r
}\r
//SetTaskMsg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");\r
\r
Sts = FFFTP_SUCCESS;\r
- if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE_BIT) == YES)\r
+ if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE) == YES)\r
{\r
Sts = ReConnectCmdSkt();\r
}\r
\r
\r
\r
+// IPv6対応\r
+\r
+typedef struct\r
+{\r
+ HANDLE h;\r
+ HWND hWnd;\r
+ u_int wMsg;\r
+ char * name;\r
+ char * buf;\r
+ int buflen;\r
+ short Family;\r
+} GETHOSTBYNAMEDATA;\r
+\r
+static DWORD WINAPI WSAAsyncGetHostByNameIPv6ThreadProc(LPVOID lpParameter)\r
+{\r
+ GETHOSTBYNAMEDATA* pData;\r
+ struct hostent* pHost;\r
+ struct addrinfo* pAddr;\r
+ struct addrinfo* p;\r
+ pHost = NULL;\r
+ pData = (GETHOSTBYNAMEDATA*)lpParameter;\r
+ if(getaddrinfo(pData->name, NULL, NULL, &pAddr) == 0)\r
+ {\r
+ p = pAddr;\r
+ while(p)\r
+ {\r
+ if(p->ai_family == pData->Family)\r
+ {\r
+ switch(p->ai_family)\r
+ {\r
+ case AF_INET:\r
+ pHost = (struct hostent*)pData->buf;\r
+ if((size_t)pData->buflen >= sizeof(struct hostent) + sizeof(char*) * 2 + sizeof(struct in_addr)\r
+ && p->ai_addrlen >= sizeof(struct sockaddr_in))\r
+ {\r
+ pHost->h_name = NULL;\r
+ pHost->h_aliases = NULL;\r
+ pHost->h_addrtype = p->ai_family;\r
+ pHost->h_length = sizeof(struct in_addr);\r
+ pHost->h_addr_list = (char**)(&pHost[1]);\r
+ pHost->h_addr_list[0] = (char*)(&pHost->h_addr_list[2]);\r
+ pHost->h_addr_list[1] = NULL;\r
+ memcpy(pHost->h_addr_list[0], &((struct sockaddr_in*)p->ai_addr)->sin_addr, sizeof(struct in_addr));\r
+ PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(sizeof(struct hostent) + sizeof(char*) * 2 + p->ai_addrlen));\r
+ }\r
+ else\r
+ PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(WSAENOBUFS << 16));\r
+ break;\r
+ case AF_INET6:\r
+ pHost = (struct hostent*)pData->buf;\r
+ if((size_t)pData->buflen >= sizeof(struct hostent) + sizeof(char*) * 2 + sizeof(struct in6_addr)\r
+ && p->ai_addrlen >= sizeof(struct sockaddr_in6))\r
+ {\r
+ pHost->h_name = NULL;\r
+ pHost->h_aliases = NULL;\r
+ pHost->h_addrtype = p->ai_family;\r
+ pHost->h_length = sizeof(struct in6_addr);\r
+ pHost->h_addr_list = (char**)(&pHost[1]);\r
+ pHost->h_addr_list[0] = (char*)(&pHost->h_addr_list[2]);\r
+ pHost->h_addr_list[1] = NULL;\r
+ memcpy(pHost->h_addr_list[0], &((struct sockaddr_in6*)p->ai_addr)->sin6_addr, sizeof(struct in6_addr));\r
+ PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(sizeof(struct hostent) + sizeof(char*) * 2 + p->ai_addrlen));\r
+ }\r
+ else\r
+ PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(WSAENOBUFS << 16));\r
+ break;\r
+ }\r
+ }\r
+ if(pHost)\r
+ break;\r
+ p = p->ai_next;\r
+ }\r
+ if(!p)\r
+ PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(ERROR_INVALID_FUNCTION << 16));\r
+ freeaddrinfo(pAddr);\r
+ }\r
+ else\r
+ PostMessage(pData->hWnd, pData->wMsg, (WPARAM)pData->h, (LPARAM)(ERROR_INVALID_FUNCTION << 16));\r
+ free(pData->name);\r
+ free(pData);\r
+ // CreateThreadが返すハンドルが重複するのを回避\r
+ Sleep(10000);\r
+ return 0;\r
+}\r
+\r
+// IPv6対応のWSAAsyncGetHostByName相当の関数\r
+// FamilyにはAF_INETまたはAF_INET6を指定可能\r
+// ただしANSI用\r
+static HANDLE WSAAsyncGetHostByNameIPv6(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family)\r
+{\r
+ HANDLE hResult;\r
+ GETHOSTBYNAMEDATA* pData;\r
+ hResult = NULL;\r
+ if(pData = malloc(sizeof(GETHOSTBYNAMEDATA)))\r
+ {\r
+ pData->hWnd = hWnd;\r
+ pData->wMsg = wMsg;\r
+ if(pData->name = malloc(sizeof(char) * (strlen(name) + 1)))\r
+ {\r
+ strcpy(pData->name, name);\r
+ pData->buf = buf;\r
+ pData->buflen = buflen;\r
+ pData->Family = Family;\r
+ if(pData->h = CreateThread(NULL, 0, WSAAsyncGetHostByNameIPv6ThreadProc, pData, CREATE_SUSPENDED, NULL))\r
+ {\r
+ ResumeThread(pData->h);\r
+ hResult = pData->h;\r
+ }\r
+ }\r
+ }\r
+ if(!hResult)\r
+ {\r
+ if(pData)\r
+ {\r
+ if(pData->name)\r
+ free(pData->name);\r
+ free(pData);\r
+ }\r
+ }\r
+ return hResult;\r
+}\r
+\r
+// WSAAsyncGetHostByNameIPv6用のWSACancelAsyncRequest相当の関数\r
+int WSACancelAsyncRequestIPv6(HANDLE hAsyncTaskHandle)\r
+{\r
+ int Result;\r
+ Result = SOCKET_ERROR;\r
+ if(TerminateThread(hAsyncTaskHandle, 0))\r
+ Result = 0;\r
+ return Result;\r
+}\r
+\r
// UTF-8対応\r
\r
static BOOL ConvertStringToPunycode(LPSTR Output, DWORD Count, LPCSTR Input)\r
return r;\r
}\r
\r
+static HANDLE WSAAsyncGetHostByNameIPv6M(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family)\r
+{\r
+ HANDLE r = NULL;\r
+ char* pa0 = NULL;\r
+ if(pa0 = AllocateStringA(strlen(name) * 4))\r
+ {\r
+ if(ConvertNameToPunycode(pa0, name))\r
+ r = WSAAsyncGetHostByNameIPv6(hWnd, wMsg, pa0, buf, buflen, Family);\r
+ }\r
+ FreeDuplicatedString(pa0);\r
+ return r;\r
+}\r
+\r
_X509_get_subject_name p_X509_get_subject_name;\r
_X509_NAME_print_ex p_X509_NAME_print_ex;\r
\r
-#define MAX_SSL_SOCKET 64\r
+#define MAX_SSL_SOCKET 16\r
\r
BOOL g_bOpenSSLLoaded;\r
HMODULE g_hOpenSSL;\r