/============================================================================*/\r
\r
#define STRICT\r
+// IPv6対応\r
+#include <winsock2.h>\r
#include <windows.h>\r
#include <stdio.h>\r
#include <stdlib.h>\r
\r
#include "common.h"\r
#include "resource.h"\r
-// UTF-8対応\r
-#include "punycode.h"\r
\r
#define USE_THIS 1\r
#define DBG_MSG 0\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 RegistAsyncTableDbase(HANDLE Async);\r
static int UnRegistAsyncTable(SOCKET s);\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
\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
\r
\r
-struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
+// IPv6対応\r
+//struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
+struct hostent *do_gethostbynameIPv4(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
{\r
#if USE_THIS\r
struct hostent *Ret;\r
DoPrintf("# Start gethostbyname");\r
#endif\r
Ret = NULL;\r
- *CancelCheckWork = NO;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
\r
// UTF-8対応\r
// hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
}\r
\r
\r
+struct hostent *do_gethostbynameIPv6(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
+{\r
+#if USE_THIS\r
+ struct hostent *Ret;\r
+ HANDLE hAsync;\r
+ int Error;\r
+\r
+#if DBG_MSG\r
+ DoPrintf("# Start gethostbyname");\r
+#endif\r
+ Ret = NULL;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
+\r
+ // UTF-8対応\r
+// hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+ hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET6);\r
+ if(hAsync != NULL)\r
+ {\r
+ RegistAsyncTableDbase(hAsync);\r
+ while((*CancelCheckWork == NO) && (AskAsyncDoneDbase(hAsync, &Error) != YES))\r
+ {\r
+ Sleep(1);\r
+ if(BackgrndMessageProc() == YES)\r
+ *CancelCheckWork = YES;\r
+ }\r
+\r
+ if(*CancelCheckWork == YES)\r
+ {\r
+ WSACancelAsyncRequest(hAsync);\r
+ }\r
+ else if(Error == 0)\r
+ {\r
+ Ret = (struct hostent *)Buf;\r
+ }\r
+ UnRegistAsyncTableDbase(hAsync);\r
+ }\r
+ return(Ret);\r
+#else\r
+ return(gethostbyname(Name));\r
+#endif\r
+}\r
+\r
+\r
\r
\r
\r
UnRegistAsyncTable(s);\r
// FTPS対応\r
// Ret = closesocket(s);\r
- Ret = closesocketS(s);\r
+ Ret = FTPS_closesocket(s);\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("# Start connect (S=%x)", s);\r
#endif\r
- *CancelCheckWork = NO;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
\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
DoPrintf("# Start recv (S=%x)", s);\r
#endif\r
*TimeOutErr = NO;\r
- *CancelCheckWork = NO;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
Ret = SOCKET_ERROR;\r
Error = 0;\r
\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
// Ret = recv(s, buf, len, flags);\r
- Ret = recvS(s, buf, len, flags);\r
+ Ret = FTPS_recv(s, buf, len, flags);\r
if(Ret != SOCKET_ERROR)\r
break;\r
- // 何故か一部のホストとWindows 2000の組み合わせで通信できないバグに暫定対応\r
- if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES && recvS(s, buf, len, MSG_PEEK) <= 0)\r
- break;\r
Error = WSAGetLastError();\r
Sleep(1);\r
if(BackgrndMessageProc() == YES)\r
DoPrintf("# Start send (S=%x)", s);\r
#endif\r
*TimeOutErr = NO;\r
- *CancelCheckWork = NO;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
Ret = SOCKET_ERROR;\r
Error = 0;\r
\r
#if DBG_MSG\r
DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");\r
#endif\r
- WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
+ // Windows 2000でFD_WRITEが通知されないことがあるバグ修正\r
+ // 毎回通知されたのはNT 4.0までのバグであり仕様ではない\r
+ // XP以降は互換性のためか毎回通知される\r
+// WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
if(BackgrndMessageProc() == YES)\r
*CancelCheckWork = YES;\r
\r
// FTPS対応\r
// 送信バッファの空き確認には影響しないが念のため\r
-// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))\r
- while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))\r
- {\r
- if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
- {\r
- Error = 1;\r
- break;\r
- }\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_write timed out");\r
- *TimeOutErr = YES;\r
- *CancelCheckWork = YES;\r
- }\r
- }\r
- }\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) != YES))\r
+// {\r
+// if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
+// {\r
+// Error = 1;\r
+// break;\r
+// }\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_write timed out");\r
+// *TimeOutErr = YES;\r
+// *CancelCheckWork = YES;\r
+// }\r
+// }\r
+// }\r
\r
if((Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO))\r
{\r
\r
// FTPS対応\r
// Ret = send(s, buf, len, flags);\r
- Ret = sendS(s, buf, len, flags);\r
+ Ret = FTPS_send(s, buf, len, flags);\r
if(Ret != SOCKET_ERROR)\r
{\r
#if DBG_MSG\r
#endif\r
break;\r
}\r
- // 何故か一部のホストとWindows 2000の組み合わせで通信できないバグに暫定対応\r
- if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
- break;\r
Error = WSAGetLastError();\r
Sleep(1);\r
if(BackgrndMessageProc() == YES)\r
}\r
\r
\r
+// 同時接続対応\r
+void RemoveReceivedData(SOCKET s)\r
+{\r
+ char buf[1024];\r
+ int len;\r
+ int Error;\r
+ while((len = FTPS_recv(s, buf, sizeof(buf), MSG_PEEK)) >= 0)\r
+ {\r
+ AskAsyncDone(s, &Error, FD_READ);\r
+ FTPS_recv(s, buf, len, 0);\r
+ }\r
+}\r
+\r
+\r
/*----- \r
*\r
* Parameter\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
-// UTF-8対応\r
-\r
-static BOOL ConvertStringToPunycode(LPSTR Output, DWORD Count, LPCSTR Input)\r
+// 同時接続対応\r
+int CheckClosedAndReconnectTrnSkt(SOCKET *Skt, int *CancelCheckWork)\r
{\r
- BOOL bResult;\r
- punycode_uint* pUnicode;\r
- punycode_uint* p;\r
- BOOL bNeeded;\r
- LPCSTR InputString;\r
- punycode_uint Length;\r
- punycode_uint OutputLength;\r
- bResult = FALSE;\r
- if(pUnicode = malloc(sizeof(punycode_uint) * strlen(Input)))\r
- {\r
- p = pUnicode;\r
- bNeeded = FALSE;\r
- InputString = Input;\r
- Length = 0;\r
- while(*InputString != '\0')\r
- {\r
- *p = 0;\r
- if((*InputString & 0x80) == 0x00)\r
- *p |= (punycode_uint)*InputString & 0x7f;\r
- else if((*InputString & 0xe0) == 0xc0)\r
- *p |= (punycode_uint)*InputString & 0x1f;\r
- else if((*InputString & 0xf0) == 0xe0)\r
- *p |= (punycode_uint)*InputString & 0x0f;\r
- else if((*InputString & 0xf8) == 0xf0)\r
- *p |= (punycode_uint)*InputString & 0x07;\r
- else if((*InputString & 0xfc) == 0xf8)\r
- *p |= (punycode_uint)*InputString & 0x03;\r
- else if((*InputString & 0xfe) == 0xfc)\r
- *p |= (punycode_uint)*InputString & 0x01;\r
- InputString++;\r
- while((*InputString & 0xc0) == 0x80)\r
- {\r
- *p = *p << 6;\r
- *p |= (punycode_uint)*InputString & 0x3f;\r
- InputString++;\r
- }\r
- if(*p >= 0x80)\r
- bNeeded = TRUE;\r
- p++;\r
- Length++;\r
- }\r
- if(bNeeded)\r
- {\r
- if(Count >= strlen("xn--") + 1)\r
- {\r
- strcpy(Output, "xn--");\r
- OutputLength = Count - strlen("xn--");\r
- if(punycode_encode(Length, pUnicode, NULL, (punycode_uint*)&OutputLength, Output + strlen("xn--")) == punycode_success)\r
- {\r
- Output[strlen("xn--") + OutputLength] = '\0';\r
- bResult = TRUE;\r
- }\r
- }\r
- }\r
- free(pUnicode);\r
- }\r
- if(!bResult)\r
- {\r
- if(Count >= strlen(Input) + 1)\r
- {\r
- strcpy(Output, Input);\r
- bResult = TRUE;\r
- }\r
- }\r
- return bResult;\r
-}\r
+ int Error;\r
+ int Sts;\r
\r
-static BOOL ConvertNameToPunycode(LPSTR Output, LPCSTR Input)\r
-{\r
- BOOL bResult;\r
- DWORD Length;\r
- char* pm0;\r
- char* pm1;\r
- char* p;\r
- char* pNext;\r
- bResult = FALSE;\r
- Length = strlen(Input);\r
- if(pm0 = AllocateStringM(Length + 1))\r
- {\r
- if(pm1 = AllocateStringM(Length * 4 + 1))\r
- {\r
- strcpy(pm0, Input);\r
- p = pm0;\r
- while(p)\r
- {\r
- if(pNext = strchr(p, '.'))\r
- {\r
- *pNext = '\0';\r
- pNext++;\r
- }\r
- if(ConvertStringToPunycode(pm1, Length * 4, p))\r
- strcat(Output, pm1);\r
- if(pNext)\r
- strcat(Output, ".");\r
- p = pNext;\r
- }\r
- bResult = TRUE;\r
- FreeDuplicatedString(pm1);\r
- }\r
- FreeDuplicatedString(pm0);\r
- }\r
- return bResult;\r
-}\r
+//SetTaskMsg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");\r
\r
-static HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen)\r
-{\r
- HANDLE r = NULL;\r
- char* pa0 = NULL;\r
- if(pa0 = AllocateStringA(strlen(name) * 4))\r
+ Sts = FFFTP_SUCCESS;\r
+ if(AskAsyncDone(*Skt, &Error, FD_CLOSE) == YES)\r
{\r
- if(ConvertNameToPunycode(pa0, name))\r
- r = WSAAsyncGetHostByName(hWnd, wMsg, pa0, buf, buflen);\r
+ Sts = ReConnectTrnSkt(Skt, CancelCheckWork);\r
}\r
- FreeDuplicatedString(pa0);\r
- return r;\r
+ return(Sts);\r
}\r
\r