1 /*=============================================================================
\r
5 ===============================================================================
\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.
\r
8 / Redistribution and use in source and binary forms, with or without
\r
9 / modification, are permitted provided that the following conditions
\r
12 / 1. Redistributions of source code must retain the above copyright
\r
13 / notice, this list of conditions and the following disclaimer.
\r
14 / 2. Redistributions in binary form must reproduce the above copyright
\r
15 / notice, this list of conditions and the following disclaimer in the
\r
16 / documentation and/or other materials provided with the distribution.
\r
18 / THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
\r
19 / IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
\r
20 / OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
\r
21 / IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
\r
22 / INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
\r
23 / BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
\r
24 / USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
\r
25 / ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
26 / (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
\r
27 / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
28 /============================================================================*/
\r
31 #include <windows.h>
\r
36 #include <windowsx.h>
\r
37 #include <commctrl.h>
\r
40 #include "resource.h"
\r
48 #define FD_CONNECT_BIT 0x0001
\r
49 #define FD_CLOSE_BIT 0x0002
\r
50 #define FD_ACCEPT_BIT 0x0004
\r
51 #define FD_READ_BIT 0x0008
\r
52 #define FD_WRITE_BIT 0x0010
\r
73 } ASYNCSIGNALDATABASE;
\r
78 //#define MAX_SIGNAL_ENTRY 10
\r
79 //#define MAX_SIGNAL_ENTRY_DBASE 5
\r
80 #define MAX_SIGNAL_ENTRY 100
\r
81 #define MAX_SIGNAL_ENTRY_DBASE 50
\r
86 /*===== プロトタイプ =====*/
\r
88 static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
\r
89 static int AskAsyncDone(SOCKET s, int *Error, int Mask);
\r
90 static int AskAsyncDoneDbase(HANDLE Async, int *Error);
\r
91 static int RegistAsyncTable(SOCKET s);
\r
92 static int RegistAsyncTableDbase(HANDLE Async);
\r
93 static int UnRegistAsyncTable(SOCKET s);
\r
94 static int UnRegistAsyncTableDbase(HANDLE Async);
\r
97 /*===== 外部参照 =====*/
\r
102 /*===== ローカルなワーク =====*/
\r
104 static const char SocketWndClass[] = "FFFTPSocketWnd";
\r
105 static HWND hWndSocket;
\r
107 static ASYNCSIGNAL Signal[MAX_SIGNAL_ENTRY];
\r
108 static ASYNCSIGNALDATABASE SignalDbase[MAX_SIGNAL_ENTRY_DBASE];
\r
110 //static HANDLE hAsyncTblAccMutex;
\r
112 static HANDLE hAsyncTblAccMutex;
\r
124 * FFFTP_SUCCESS/FFFTP_FAIL
\r
125 *----------------------------------------------------------------------------*/
\r
127 int MakeSocketWin(HWND hWnd, HINSTANCE hInst)
\r
133 wClass.cbSize = sizeof(WNDCLASSEX);
\r
135 wClass.lpfnWndProc = SocketWndProc;
\r
136 wClass.cbClsExtra = 0;
\r
137 wClass.cbWndExtra = 0;
\r
138 wClass.hInstance = hInst;
\r
139 wClass.hIcon = NULL;
\r
140 wClass.hCursor = NULL;
\r
141 wClass.hbrBackground = (HBRUSH)CreateSolidBrush(GetSysColor(COLOR_INFOBK));
\r
142 wClass.lpszMenuName = NULL;
\r
143 wClass.lpszClassName = SocketWndClass;
\r
144 wClass.hIconSm = NULL;
\r
145 RegisterClassEx(&wClass);
\r
148 hWndSocket = CreateWindowEx(0, SocketWndClass, NULL,
\r
149 WS_BORDER | WS_POPUP,
\r
151 hWnd, NULL, hInst, NULL);
\r
153 if(hWndSocket != NULL)
\r
155 // hAsyncTblAccMutex = CreateMutex(NULL, FALSE, NULL);
\r
158 // for(i = 0; i < MAX_SIGNAL_ENTRY; i++)
\r
159 // Signal[i].Socket = INVALID_SOCKET;
\r
160 // for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++)
\r
161 // SignalDbase[i].Async = 0;
\r
162 if(hAsyncTblAccMutex = CreateMutex(NULL, FALSE, NULL))
\r
164 for(i = 0; i < MAX_SIGNAL_ENTRY; i++)
\r
165 Signal[i].Socket = INVALID_SOCKET;
\r
166 for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++)
\r
167 SignalDbase[i].Async = 0;
\r
169 Sts = FFFTP_SUCCESS;
\r
182 *----------------------------------------------------------------------------*/
\r
184 void DeleteSocketWin(void)
\r
186 // CloseHandle(hAsyncTblAccMutex);
\r
188 CloseHandle(hAsyncTblAccMutex);
\r
189 hAsyncTblAccMutex = NULL;
\r
191 if(hWndSocket != NULL)
\r
192 DestroyWindow(hWndSocket);
\r
200 * HWND hWnd : ウインドウハンドル
\r
201 * UINT message : メッセージ番号
\r
202 * WPARAM wParam : メッセージの WPARAM 引数
\r
203 * LPARAM lParam : メッセージの LPARAM 引数
\r
207 *----------------------------------------------------------------------------*/
\r
209 static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
\r
215 case WM_ASYNC_SOCKET :
\r
217 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
218 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)
\r
220 if(Signal[Pos].Socket == (SOCKET)wParam)
\r
222 Signal[Pos].Error = WSAGETSELECTERROR(lParam);
\r
224 if(WSAGETSELECTERROR(lParam) != 0)
\r
225 DoPrintf("####### Signal: error (%d)", WSAGETSELECTERROR(lParam));
\r
228 switch(WSAGETSELECTEVENT(lParam))
\r
231 Signal[Pos].FdConnect = 1;
\r
233 DoPrintf("####### Signal: connect (S=%x)", Signal[Pos].Socket);
\r
238 Signal[Pos].FdClose = 1;
\r
240 DoPrintf("####### Signal: close (S=%x)", Signal[Pos].Socket);
\r
242 //SetTaskMsg("####### Signal: close (%d) (S=%x)", Pos, Signal[Pos].Socket);
\r
246 Signal[Pos].FdAccept = 1;
\r
248 DoPrintf("####### Signal: accept (S=%x)", Signal[Pos].Socket);
\r
253 Signal[Pos].FdRead = 1;
\r
255 DoPrintf("####### Signal: read (S=%x)", Signal[Pos].Socket);
\r
260 Signal[Pos].FdWrite = 1;
\r
262 DoPrintf("####### Signal: write (S=%x)", Signal[Pos].Socket);
\r
270 ReleaseMutex(hAsyncTblAccMutex);
\r
273 case WM_ASYNC_DBASE :
\r
275 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
276 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)
\r
278 if(SignalDbase[Pos].Async == (HANDLE)wParam)
\r
280 if(HIWORD(lParam) != 0)
\r
282 SignalDbase[Pos].ErrorDb = 1;
\r
284 DoPrintf("##### SignalDatabase: error");
\r
287 SignalDbase[Pos].Done = 1;
\r
289 DoPrintf("##### SignalDatabase: Done");
\r
294 // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり
\r
295 if(Pos == MAX_SIGNAL_ENTRY_DBASE)
\r
297 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)
\r
299 if(SignalDbase[Pos].Async == 0)
\r
301 SignalDbase[Pos].Async = (HANDLE)wParam;
\r
302 SignalDbase[Pos].Done = 0;
\r
303 SignalDbase[Pos].ErrorDb = 0;
\r
304 if(HIWORD(lParam) != 0)
\r
306 SignalDbase[Pos].ErrorDb = 1;
\r
308 DoPrintf("##### SignalDatabase: error");
\r
311 SignalDbase[Pos].Done = 1;
\r
313 DoPrintf("##### SignalDatabase: Done");
\r
320 ReleaseMutex(hAsyncTblAccMutex);
\r
324 return(DefWindowProc(hWnd, message, wParam, lParam));
\r
339 *----------------------------------------------------------------------------*/
\r
341 static int AskAsyncDone(SOCKET s, int *Error, int Mask)
\r
347 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
350 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)
\r
352 if(Signal[Pos].Socket == s)
\r
354 *Error = Signal[Pos].Error;
\r
355 if(Signal[Pos].Error != 0)
\r
357 if((Mask & FD_CONNECT_BIT) && (Signal[Pos].FdConnect != 0))
\r
361 DoPrintf("### Ask: connect (Sts=%d, Error=%d)", Sts, *Error);
\r
364 if((Mask & FD_CLOSE_BIT) && (Signal[Pos].FdClose != 0))
\r
365 // if(Mask & FD_CLOSE_BIT)
\r
369 DoPrintf("### Ask: close (Sts=%d, Error=%d)", Sts, *Error);
\r
372 if((Mask & FD_ACCEPT_BIT) && (Signal[Pos].FdAccept != 0))
\r
374 Signal[Pos].FdAccept = 0;
\r
377 DoPrintf("### Ask: accept (Sts=%d, Error=%d)", Sts, *Error);
\r
380 if((Mask & FD_READ_BIT) && (Signal[Pos].FdRead != 0))
\r
382 Signal[Pos].FdRead = 0;
\r
385 DoPrintf("### Ask: read (Sts=%d, Error=%d)", Sts, *Error);
\r
388 if((Mask & FD_WRITE_BIT) && (Signal[Pos].FdWrite != 0))
\r
390 Signal[Pos].FdWrite = 0;
\r
393 DoPrintf("### Ask: write (Sts=%d, Error=%d)", Sts, *Error);
\r
400 ReleaseMutex(hAsyncTblAccMutex);
\r
402 if(Pos == MAX_SIGNAL_ENTRY)
\r
404 if(Mask & FD_CLOSE_BIT)
\r
410 MessageBox(GetMainHwnd(), "AskAsyncDone called with unregisterd socket.", "FFFTP inner error", MB_OK);
\r
425 *----------------------------------------------------------------------------*/
\r
427 static int AskAsyncDoneDbase(HANDLE Async, int *Error)
\r
433 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
436 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)
\r
438 if(SignalDbase[Pos].Async == Async)
\r
440 if(SignalDbase[Pos].Done != 0)
\r
442 *Error = SignalDbase[Pos].ErrorDb;
\r
445 DoPrintf("### Ask: Dbase (Sts=%d, Error=%d)", Sts, *Error);
\r
452 ReleaseMutex(hAsyncTblAccMutex);
\r
454 if(Pos == MAX_SIGNAL_ENTRY_DBASE)
\r
456 MessageBox(GetMainHwnd(), "AskAsyncDoneDbase called with unregisterd handle.", "FFFTP inner error", MB_OK);
\r
471 *----------------------------------------------------------------------------*/
\r
473 static int RegistAsyncTable(SOCKET s)
\r
479 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
481 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)
\r
483 if(Signal[Pos].Socket == s)
\r
485 // 強制的に閉じられたソケットがあると重複する可能性あり
\r
486 // MessageBox(GetMainHwnd(), "Async socket already registerd.", "FFFTP inner error", MB_OK);
\r
487 Signal[Pos].Socket = INVALID_SOCKET;
\r
492 ReleaseMutex(hAsyncTblAccMutex);
\r
494 if(Pos == MAX_SIGNAL_ENTRY)
\r
497 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
498 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)
\r
500 if(Signal[Pos].Socket == INVALID_SOCKET)
\r
503 //SetTaskMsg("############### Regist socket (%d)", Pos);
\r
505 Signal[Pos].Socket = s;
\r
506 Signal[Pos].Error = 0;
\r
507 Signal[Pos].FdConnect = 0;
\r
508 Signal[Pos].FdClose = 0;
\r
509 Signal[Pos].FdAccept = 0;
\r
510 Signal[Pos].FdRead = 0;
\r
511 Signal[Pos].FdWrite = 0;
\r
517 ReleaseMutex(hAsyncTblAccMutex);
\r
519 if(Pos == MAX_SIGNAL_ENTRY)
\r
521 MessageBox(GetMainHwnd(), "No more async regist space.", "FFFTP inner error", MB_OK);
\r
537 *----------------------------------------------------------------------------*/
\r
539 static int RegistAsyncTableDbase(HANDLE Async)
\r
545 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
547 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)
\r
549 if(SignalDbase[Pos].Async == Async)
\r
551 // 強制的に閉じられたハンドルがあると重複する可能性あり
\r
552 // MessageBox(GetMainHwnd(), "Async handle already registerd.", "FFFTP inner error", MB_OK);
\r
553 // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり
\r
558 ReleaseMutex(hAsyncTblAccMutex);
\r
560 if(Pos == MAX_SIGNAL_ENTRY_DBASE)
\r
563 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
564 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)
\r
566 if(SignalDbase[Pos].Async == 0)
\r
569 //SetTaskMsg("############### Regist dbase (%d)", Pos);
\r
571 SignalDbase[Pos].Async = Async;
\r
572 SignalDbase[Pos].Done = 0;
\r
573 SignalDbase[Pos].ErrorDb = 0;
\r
579 ReleaseMutex(hAsyncTblAccMutex);
\r
581 if(Pos == MAX_SIGNAL_ENTRY_DBASE)
\r
583 MessageBox(GetMainHwnd(), "No more async dbase regist space.", "FFFTP inner error", MB_OK);
\r
599 *----------------------------------------------------------------------------*/
\r
601 static int UnRegistAsyncTable(SOCKET s)
\r
607 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
609 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)
\r
611 if(Signal[Pos].Socket == s)
\r
614 //SetTaskMsg("############### UnRegist socket (%d)", Pos);
\r
616 Signal[Pos].Socket = INVALID_SOCKET;
\r
622 ReleaseMutex(hAsyncTblAccMutex);
\r
634 *----------------------------------------------------------------------------*/
\r
636 static int UnRegistAsyncTableDbase(HANDLE Async)
\r
642 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);
\r
644 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)
\r
646 if(SignalDbase[Pos].Async == Async)
\r
649 //SetTaskMsg("############### UnRegist dbase (%d)", Pos);
\r
651 SignalDbase[Pos].Async = 0;
\r
657 ReleaseMutex(hAsyncTblAccMutex);
\r
668 struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)
\r
671 struct hostent *Ret;
\r
676 DoPrintf("# Start gethostbyname");
\r
679 *CancelCheckWork = NO;
\r
681 hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);
\r
684 RegistAsyncTableDbase(hAsync);
\r
685 while((*CancelCheckWork == NO) && (AskAsyncDoneDbase(hAsync, &Error) != YES))
\r
688 if(BackgrndMessageProc() == YES)
\r
689 *CancelCheckWork = YES;
\r
692 if(*CancelCheckWork == YES)
\r
694 WSACancelAsyncRequest(hAsync);
\r
696 else if(Error == 0)
\r
698 Ret = (struct hostent *)Buf;
\r
700 UnRegistAsyncTableDbase(hAsync);
\r
704 return(gethostbyname(Name));
\r
712 SOCKET do_socket(int af, int type, int protocol)
\r
716 Ret = socket(af, type, protocol);
\r
717 if(Ret != INVALID_SOCKET)
\r
719 RegistAsyncTable(Ret);
\r
722 DoPrintf("# do_socket (S=%x)", Ret);
\r
729 int do_closesocket(SOCKET s)
\r
734 int CancelCheckWork;
\r
737 DoPrintf("# Start close (S=%x)", s);
\r
739 CancelCheckWork = NO;
\r
742 // Ret = closesocket(s);
\r
743 if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)
\r
744 Ret = closesocketS(s);
\r
746 Ret = closesocketS(s);
\r
747 if(Ret == SOCKET_ERROR)
\r
750 while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE_BIT) != YES))
\r
753 if(BackgrndMessageProc() == YES)
\r
754 CancelCheckWork = YES;
\r
757 if((CancelCheckWork == NO) && (Error == 0))
\r
761 WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);
\r
762 if(BackgrndMessageProc() == YES)
\r
763 CancelCheckWork = YES;
\r
764 UnRegistAsyncTable(s);
\r
767 DoPrintf("# Exit close");
\r
771 return(closesocket(s));
\r
780 int do_connect(SOCKET s, const struct sockaddr *name, int namelen, int *CancelCheckWork)
\r
787 DoPrintf("# Start connect (S=%x)", s);
\r
789 *CancelCheckWork = NO;
\r
792 DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");
\r
794 Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);
\r
795 if(Ret != SOCKET_ERROR)
\r
798 // Ret = connect(s, name, namelen);
\r
799 if(AskCryptMode() == CRYPT_FTPIS)
\r
800 Ret = connectS(s, name, namelen);
\r
802 Ret = connect(s, name, namelen);
\r
803 if(Ret == SOCKET_ERROR)
\r
808 while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT_BIT) != YES))
\r
811 if(BackgrndMessageProc() == YES)
\r
812 *CancelCheckWork = YES;
\r
815 if(*CancelCheckWork == YES)
\r
821 // Error = WSAGetLastError();
\r
822 DoPrintf("#### Connect: Error=%d", Error);
\r
825 while((Ret != 0) && (Error == WSAEWOULDBLOCK));
\r
829 DoPrintf("#### Connect: AsyncSelect error (%d)", WSAGetLastError());
\r
832 DoPrintf("# Exit connect (%d)", Ret);
\r
836 return(connect(s, name, namelen));
\r
844 int do_listen(SOCKET s, int backlog)
\r
850 DoPrintf("# Start listen (S=%x)", s);
\r
851 DoPrintf("## Async set: FD_CLOSE|FD_ACCEPT");
\r
854 Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CLOSE | FD_ACCEPT);
\r
855 if(Ret != SOCKET_ERROR)
\r
856 Ret = listen(s, backlog);
\r
859 DoPrintf("# Exit listen (%d)", Ret);
\r
866 SOCKET do_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
\r
870 int CancelCheckWork;
\r
874 DoPrintf("# Start accept (S=%x)", s);
\r
876 CancelCheckWork = NO;
\r
877 Ret2 = INVALID_SOCKET;
\r
880 while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT_BIT) != YES))
\r
882 if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)
\r
888 if(BackgrndMessageProc() == YES)
\r
889 CancelCheckWork = YES;
\r
892 if((CancelCheckWork == NO) && (Error == 0))
\r
897 // Ret2 = accept(s, addr, addrlen);
\r
898 if(AskCryptMode() == CRYPT_FTPIS)
\r
899 Ret2 = acceptS(s, addr, addrlen);
\r
901 Ret2 = accept(s, addr, addrlen);
\r
902 if(Ret2 != INVALID_SOCKET)
\r
905 DoPrintf("## do_sccept (S=%x)", Ret2);
\r
906 DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");
\r
908 RegistAsyncTable(Ret2);
\r
909 if(WSAAsyncSelect(Ret2, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE) == SOCKET_ERROR)
\r
911 do_closesocket(Ret2);
\r
912 Ret2 = INVALID_SOCKET;
\r
916 Error = WSAGetLastError();
\r
918 if(BackgrndMessageProc() == YES)
\r
921 while(Error == WSAEWOULDBLOCK);
\r
925 DoPrintf("# Exit accept");
\r
929 return(accept(s, addr, addrlen));
\r
936 /*----- recv相当の関数 --------------------------------------------------------
\r
940 * char *buf : データを読み込むバッファ
\r
942 * int flags : recvに与えるフラグ
\r
943 * int *TimeOutErr : タイムアウトしたかどうかを返すワーク
\r
946 * int : recvの戻り値と同じ
\r
949 * タイムアウトの時は TimeOut=YES、Ret=SOCKET_ERROR になる
\r
950 *----------------------------------------------------------------------------*/
\r
951 int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *CancelCheckWork)
\r
960 DoPrintf("# Start recv (S=%x)", s);
\r
963 *CancelCheckWork = NO;
\r
964 Ret = SOCKET_ERROR;
\r
971 // OpenSSLでは受信確認はFD_READが複数回受信される可能性がある
\r
972 // while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES))
\r
973 while(AskCryptMode() == CRYPT_NONE && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES))
\r
975 if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)
\r
981 if(BackgrndMessageProc() == YES)
\r
982 *CancelCheckWork = YES;
\r
983 else if(TimeOut != 0)
\r
986 ElapseTime -= StartTime;
\r
987 if(ElapseTime >= TimeOut)
\r
989 DoPrintf("do_recv timed out");
\r
991 *CancelCheckWork = YES;
\r
996 if(/*(Ret != 0) && */(Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO))
\r
1001 DoPrintf("## recv()");
\r
1005 // Ret = recv(s, buf, len, flags);
\r
1006 if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)
\r
1007 Ret = recvS(s, buf, len, flags);
\r
1009 Ret = recv(s, buf, len, flags);
\r
1010 if(Ret != SOCKET_ERROR)
\r
1012 Error = WSAGetLastError();
\r
1014 if(BackgrndMessageProc() == YES)
\r
1017 // 受信確認をバイパスしたためここでタイムアウトの確認
\r
1018 if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)
\r
1020 if(BackgrndMessageProc() == YES)
\r
1021 *CancelCheckWork = YES;
\r
1023 else if(TimeOut != 0)
\r
1025 time(&ElapseTime);
\r
1026 ElapseTime -= StartTime;
\r
1027 if(ElapseTime >= TimeOut)
\r
1029 DoPrintf("do_recv timed out");
\r
1030 *TimeOutErr = YES;
\r
1031 *CancelCheckWork = YES;
\r
1034 if(*CancelCheckWork == YES)
\r
1037 while(Error == WSAEWOULDBLOCK);
\r
1040 if(BackgrndMessageProc() == YES)
\r
1041 Ret = SOCKET_ERROR;
\r
1044 DoPrintf("# Exit recv (%d)", Ret);
\r
1048 return(recv(s, buf, len, flags));
\r
1054 int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int *CancelCheckWork)
\r
1059 time_t ElapseTime;
\r
1063 DoPrintf("# Start send (S=%x)", s);
\r
1066 *CancelCheckWork = NO;
\r
1067 Ret = SOCKET_ERROR;
\r
1074 DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");
\r
1076 WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);
\r
1077 if(BackgrndMessageProc() == YES)
\r
1078 *CancelCheckWork = YES;
\r
1081 // 送信バッファの空き確認には影響しないが念のため
\r
1082 // while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))
\r
1083 while(AskCryptMode() == CRYPT_NONE && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))
\r
1085 if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)
\r
1092 if(BackgrndMessageProc() == YES)
\r
1093 *CancelCheckWork = YES;
\r
1094 else if(TimeOut != 0)
\r
1096 time(&ElapseTime);
\r
1097 ElapseTime -= StartTime;
\r
1098 if(ElapseTime >= TimeOut)
\r
1100 DoPrintf("do_write timed out");
\r
1101 *TimeOutErr = YES;
\r
1102 *CancelCheckWork = YES;
\r
1107 if((Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO))
\r
1112 DoPrintf("## send()");
\r
1116 // Ret = send(s, buf, len, flags);
\r
1117 if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)
\r
1118 Ret = sendS(s, buf, len, flags);
\r
1120 Ret = send(s, buf, len, flags);
\r
1121 if(Ret != SOCKET_ERROR)
\r
1124 DoPrintf("## send() OK");
\r
1128 Error = WSAGetLastError();
\r
1130 if(BackgrndMessageProc() == YES)
\r
1133 // 送信バッファ確認をバイパスしたためここでタイムアウトの確認
\r
1134 if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)
\r
1136 if(BackgrndMessageProc() == YES)
\r
1137 *CancelCheckWork = YES;
\r
1139 else if(TimeOut != 0)
\r
1141 time(&ElapseTime);
\r
1142 ElapseTime -= StartTime;
\r
1143 if(ElapseTime >= TimeOut)
\r
1145 DoPrintf("do_recv timed out");
\r
1146 *TimeOutErr = YES;
\r
1147 *CancelCheckWork = YES;
\r
1150 if(*CancelCheckWork == YES)
\r
1153 while(Error == WSAEWOULDBLOCK);
\r
1156 if(BackgrndMessageProc() == YES)
\r
1157 Ret = SOCKET_ERROR;
\r
1160 DoPrintf("# Exit send (%d)", Ret);
\r
1164 return(send(s, buf, len, flags));
\r
1175 * FFFTP_SUCCESS/FFFTP_FAIL
\r
1176 *----------------------------------------------------------------------------*/
\r
1178 int CheckClosedAndReconnect(void)
\r
1183 //SetTaskMsg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
\r
1185 Sts = FFFTP_SUCCESS;
\r
1186 if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE_BIT) == YES)
\r
1188 Sts = ReConnectCmdSkt();
\r