OSDN Git Service

This version may be nearly stable.
[ffftp/ffftp.git] / socket.c
1 /*=============================================================================\r
2 *\r
3 *                                                                       \83\\83P\83b\83g\r
4 *\r
5 ===============================================================================\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.\r
7 /\r
8 / Redistribution and use in source and binary forms, with or without \r
9 / modification, are permitted provided that the following conditions \r
10 / are met:\r
11 /\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
17 /\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
29 \r
30 #define STRICT\r
31 #include <windows.h>\r
32 #include <stdio.h>\r
33 #include <stdlib.h>\r
34 #include <string.h>\r
35 #include <time.h>\r
36 #include <windowsx.h>\r
37 #include <commctrl.h>\r
38 \r
39 #include "common.h"\r
40 #include "resource.h"\r
41 \r
42 #define USE_THIS        1\r
43 #define DBG_MSG         0\r
44 \r
45 \r
46 \r
47 \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
53 \r
54 \r
55 \r
56 \r
57 \r
58 typedef struct {\r
59         SOCKET Socket;\r
60         int FdConnect;\r
61         int FdClose;\r
62         int FdAccept;\r
63         int FdRead;\r
64         int FdWrite;\r
65         int Error;\r
66 } ASYNCSIGNAL;\r
67 \r
68 \r
69 typedef struct {\r
70         HANDLE Async;\r
71         int Done;\r
72         int ErrorDb;\r
73 } ASYNCSIGNALDATABASE;\r
74 \r
75 \r
76 // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
77 // \94O\82Ì\82½\82ß\83e\81[\83u\83\8b\82ð\91\9d\97Ê\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
82 \r
83 \r
84 \r
85 \r
86 /*===== \83v\83\8d\83g\83^\83C\83v =====*/\r
87 \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
95 \r
96 \r
97 /*===== \8aO\95\94\8eQ\8fÆ =====*/\r
98 \r
99 extern int TimeOut;\r
100 \r
101 \r
102 /*===== \83\8d\81[\83J\83\8b\82È\83\8f\81[\83N =====*/\r
103 \r
104 static const char SocketWndClass[] = "FFFTPSocketWnd";\r
105 static HWND hWndSocket;\r
106 \r
107 static ASYNCSIGNAL Signal[MAX_SIGNAL_ENTRY];\r
108 static ASYNCSIGNALDATABASE SignalDbase[MAX_SIGNAL_ENTRY_DBASE];\r
109 \r
110 //static HANDLE hAsyncTblAccMutex;\r
111 // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
112 static HANDLE hAsyncTblAccMutex;\r
113 \r
114 \r
115 \r
116 \r
117 \r
118 /*----- \r
119 *\r
120 *       Parameter\r
121 *\r
122 *       Return Value\r
123 *               int \83X\83e\81[\83^\83X\r
124 *                       SUCCESS/FAIL\r
125 *----------------------------------------------------------------------------*/\r
126 \r
127 int MakeSocketWin(HWND hWnd, HINSTANCE hInst)\r
128 {\r
129         int i;\r
130         int Sts;\r
131         WNDCLASSEX wClass;\r
132 \r
133         wClass.cbSize        = sizeof(WNDCLASSEX);\r
134         wClass.style         = 0;\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
146 \r
147         Sts = FAIL;\r
148         hWndSocket = CreateWindowEx(0, SocketWndClass, NULL,\r
149                         WS_BORDER | WS_POPUP,\r
150                         0, 0, 0, 0,\r
151                         hWnd, NULL, hInst, NULL);\r
152 \r
153         if(hWndSocket != NULL)\r
154         {\r
155 //              hAsyncTblAccMutex = CreateMutex(NULL, FALSE, NULL);\r
156 \r
157                 // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\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
163                 {\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
168                 }\r
169                 Sts = SUCCESS;\r
170         }\r
171         return(Sts);\r
172 }\r
173 \r
174 \r
175 /*----- \r
176 *\r
177 *       Parameter\r
178 *               \82È\82µ\r
179 *\r
180 *       Return Value\r
181 *               \82È\82µ\r
182 *----------------------------------------------------------------------------*/\r
183 \r
184 void DeleteSocketWin(void)\r
185 {\r
186 //      CloseHandle(hAsyncTblAccMutex);\r
187         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
188         CloseHandle(hAsyncTblAccMutex);\r
189         hAsyncTblAccMutex = NULL;\r
190 \r
191         if(hWndSocket != NULL)\r
192                 DestroyWindow(hWndSocket);\r
193         return;\r
194 }\r
195 \r
196 \r
197 /*----- \r
198 *\r
199 *       Parameter\r
200 *               HWND hWnd : \83E\83C\83\93\83h\83E\83n\83\93\83h\83\8b\r
201 *               UINT message : \83\81\83b\83Z\81[\83W\94Ô\8d\86\r
202 *               WPARAM wParam : \83\81\83b\83Z\81[\83W\82Ì WPARAM \88ø\90\94\r
203 *               LPARAM lParam : \83\81\83b\83Z\81[\83W\82Ì LPARAM \88ø\90\94\r
204 *\r
205 *       Return Value\r
206 *               BOOL TRUE/FALSE\r
207 *----------------------------------------------------------------------------*/\r
208 \r
209 static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
210 {\r
211         int Pos;\r
212 \r
213         switch(message)\r
214         {\r
215                 case WM_ASYNC_SOCKET :\r
216                         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
217                         WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
218                         for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
219                         {\r
220                                 if(Signal[Pos].Socket == (SOCKET)wParam)\r
221                                 {\r
222                                         Signal[Pos].Error = WSAGETSELECTERROR(lParam);\r
223 #if DBG_MSG\r
224                                         if(WSAGETSELECTERROR(lParam) != 0)\r
225                                                 DoPrintf("####### Signal: error (%d)", WSAGETSELECTERROR(lParam));\r
226 #endif\r
227 \r
228                                         switch(WSAGETSELECTEVENT(lParam))\r
229                                         {\r
230                                                 case FD_CONNECT :\r
231                                                         Signal[Pos].FdConnect = 1;\r
232 #if DBG_MSG\r
233                                                         DoPrintf("####### Signal: connect (S=%x)", Signal[Pos].Socket);\r
234 #endif\r
235                                                         break;\r
236 \r
237                                                 case FD_CLOSE :\r
238                                                         Signal[Pos].FdClose = 1;\r
239 #if DBG_MSG\r
240                                                         DoPrintf("####### Signal: close (S=%x)", Signal[Pos].Socket);\r
241 #endif\r
242 //SetTaskMsg("####### Signal: close (%d) (S=%x)", Pos, Signal[Pos].Socket);\r
243                                                         break;\r
244 \r
245                                                 case FD_ACCEPT :\r
246                                                         Signal[Pos].FdAccept = 1;\r
247 #if DBG_MSG\r
248                                                         DoPrintf("####### Signal: accept (S=%x)", Signal[Pos].Socket);\r
249 #endif\r
250                                                         break;\r
251 \r
252                                                 case FD_READ :\r
253                                                         Signal[Pos].FdRead = 1;\r
254 #if DBG_MSG\r
255                                                         DoPrintf("####### Signal: read (S=%x)", Signal[Pos].Socket);\r
256 #endif\r
257                                                         break;\r
258 \r
259                                                 case FD_WRITE :\r
260                                                         Signal[Pos].FdWrite = 1;\r
261 #if DBG_MSG\r
262                                                         DoPrintf("####### Signal: write (S=%x)", Signal[Pos].Socket);\r
263 #endif\r
264                                                         break;\r
265                                         }\r
266                                         break;\r
267                                 }\r
268                         }\r
269                         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
270                         ReleaseMutex(hAsyncTblAccMutex);\r
271                         break;\r
272 \r
273                 case WM_ASYNC_DBASE :\r
274                         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
275                         WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
276                         for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
277                         {\r
278                                 if(SignalDbase[Pos].Async == (HANDLE)wParam)\r
279                                 {\r
280                                         if(HIWORD(lParam) != 0)\r
281                                         {\r
282                                                 SignalDbase[Pos].ErrorDb = 1;\r
283 #if DBG_MSG\r
284                                                 DoPrintf("##### SignalDatabase: error");\r
285 #endif\r
286                                         }\r
287                                         SignalDbase[Pos].Done = 1;\r
288 #if DBG_MSG\r
289                                         DoPrintf("##### SignalDatabase: Done");\r
290 #endif\r
291                                         break;\r
292                                 }\r
293                         }\r
294                         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
295                         ReleaseMutex(hAsyncTblAccMutex);\r
296                         break;\r
297 \r
298                 default :\r
299                         return(DefWindowProc(hWnd, message, wParam, lParam));\r
300         }\r
301     return(0);\r
302 }\r
303 \r
304 \r
305 \r
306 \r
307 /*----- \r
308 *\r
309 *       Parameter\r
310 *               \r
311 *\r
312 *       Return Value\r
313 *               \r
314 *----------------------------------------------------------------------------*/\r
315 \r
316 static int AskAsyncDone(SOCKET s, int *Error, int Mask)\r
317 {\r
318         int Sts;\r
319         int Pos;\r
320 \r
321         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
322         WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
323         Sts = NO;\r
324         *Error = 0;\r
325         for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
326         {\r
327                 if(Signal[Pos].Socket == s)\r
328                 {\r
329                         *Error = Signal[Pos].Error;\r
330                         if(Signal[Pos].Error != 0)\r
331                                 Sts = YES;\r
332                         if((Mask & FD_CONNECT_BIT) && (Signal[Pos].FdConnect != 0))\r
333                         {\r
334                                 Sts = YES;\r
335 #if DBG_MSG\r
336                                 DoPrintf("### Ask: connect (Sts=%d, Error=%d)", Sts, *Error);\r
337 #endif\r
338                         }\r
339                         if((Mask & FD_CLOSE_BIT) && (Signal[Pos].FdClose != 0))\r
340 //                      if(Mask & FD_CLOSE_BIT)\r
341                         {\r
342                                 Sts = YES;\r
343 #if DBG_MSG\r
344                                 DoPrintf("### Ask: close (Sts=%d, Error=%d)", Sts, *Error);\r
345 #endif\r
346                         }\r
347                         if((Mask & FD_ACCEPT_BIT) && (Signal[Pos].FdAccept != 0))\r
348                         {\r
349                                 Signal[Pos].FdAccept = 0;\r
350                                 Sts = YES;\r
351 #if DBG_MSG\r
352                                 DoPrintf("### Ask: accept (Sts=%d, Error=%d)", Sts, *Error);\r
353 #endif\r
354                         }\r
355                         if((Mask & FD_READ_BIT) && (Signal[Pos].FdRead != 0))\r
356                         {\r
357                                 Signal[Pos].FdRead = 0;\r
358                                 Sts = YES;\r
359 #if DBG_MSG\r
360                                 DoPrintf("### Ask: read (Sts=%d, Error=%d)", Sts, *Error);\r
361 #endif\r
362                         }\r
363                         if((Mask & FD_WRITE_BIT) && (Signal[Pos].FdWrite != 0))\r
364                         {\r
365                                 Signal[Pos].FdWrite = 0;\r
366                                 Sts = YES;\r
367 #if DBG_MSG\r
368                                 DoPrintf("### Ask: write (Sts=%d, Error=%d)", Sts, *Error);\r
369 #endif\r
370                         }\r
371                         break;\r
372                 }\r
373         }\r
374         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
375         ReleaseMutex(hAsyncTblAccMutex);\r
376 \r
377         if(Pos == MAX_SIGNAL_ENTRY)\r
378         {\r
379                 if(Mask & FD_CLOSE_BIT)\r
380                 {\r
381                                 Sts = YES;\r
382                 }\r
383                 else\r
384                 {\r
385                         MessageBox(GetMainHwnd(), "AskAsyncDone called with unregisterd socket.", "FFFTP inner error", MB_OK);\r
386                         exit(1);\r
387                 }\r
388         }\r
389         return(Sts);\r
390 }\r
391 \r
392 \r
393 /*----- \r
394 *\r
395 *       Parameter\r
396 *               \r
397 *\r
398 *       Return Value\r
399 *               \r
400 *----------------------------------------------------------------------------*/\r
401 \r
402 static int AskAsyncDoneDbase(HANDLE Async, int *Error)\r
403 {\r
404         int Sts;\r
405         int Pos;\r
406 \r
407         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
408         WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
409         Sts = NO;\r
410         *Error = 0;\r
411         for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
412         {\r
413                 if(SignalDbase[Pos].Async == Async)\r
414                 {\r
415                         if(SignalDbase[Pos].Done != 0)\r
416                         {\r
417                                 *Error = SignalDbase[Pos].ErrorDb;\r
418                                 Sts = YES;\r
419 #if DBG_MSG\r
420                                 DoPrintf("### Ask: Dbase (Sts=%d, Error=%d)", Sts, *Error);\r
421 #endif\r
422                         }\r
423                         break;\r
424                 }\r
425         }\r
426         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
427         ReleaseMutex(hAsyncTblAccMutex);\r
428 \r
429         if(Pos == MAX_SIGNAL_ENTRY_DBASE)\r
430         {\r
431                 MessageBox(GetMainHwnd(), "AskAsyncDoneDbase called with unregisterd handle.", "FFFTP inner error", MB_OK);\r
432                 exit(1);\r
433         }\r
434         return(Sts);\r
435 }\r
436 \r
437 \r
438 \r
439 /*----- \r
440 *\r
441 *       Parameter\r
442 *               \r
443 *\r
444 *       Return Value\r
445 *               \r
446 *----------------------------------------------------------------------------*/\r
447 \r
448 static int RegistAsyncTable(SOCKET s)\r
449 {\r
450         int Sts;\r
451         int Pos;\r
452 \r
453         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
454         WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
455         Sts = NO;\r
456         for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
457         {\r
458                 if(Signal[Pos].Socket == s)\r
459                 {\r
460                         MessageBox(GetMainHwnd(), "Async socket already registerd.", "FFFTP inner error", MB_OK);\r
461                         break;\r
462                 }\r
463         }\r
464         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
465         ReleaseMutex(hAsyncTblAccMutex);\r
466 \r
467         if(Pos == MAX_SIGNAL_ENTRY)\r
468         {\r
469                 // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
470                 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
471                 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
472                 {\r
473                         if(Signal[Pos].Socket == INVALID_SOCKET)\r
474                         {\r
475 \r
476 //SetTaskMsg("############### Regist socket (%d)", Pos);\r
477 \r
478                                 Signal[Pos].Socket = s;\r
479                                 Signal[Pos].Error = 0;\r
480                                 Signal[Pos].FdConnect = 0;\r
481                                 Signal[Pos].FdClose = 0;\r
482                                 Signal[Pos].FdAccept = 0;\r
483                                 Signal[Pos].FdRead = 0;\r
484                                 Signal[Pos].FdWrite = 0;\r
485                                 Sts = YES;\r
486                                 break;\r
487                         }\r
488                 }\r
489                 // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
490                 ReleaseMutex(hAsyncTblAccMutex);\r
491 \r
492                 if(Pos == MAX_SIGNAL_ENTRY)\r
493                 {\r
494                         MessageBox(GetMainHwnd(), "No more async regist space.", "FFFTP inner error", MB_OK);\r
495                         exit(1);\r
496                 }\r
497         }\r
498 \r
499         return(Sts);\r
500 }\r
501 \r
502 \r
503 /*----- \r
504 *\r
505 *       Parameter\r
506 *               \r
507 *\r
508 *       Return Value\r
509 *               \r
510 *----------------------------------------------------------------------------*/\r
511 \r
512 static int RegistAsyncTableDbase(HANDLE Async)\r
513 {\r
514         int Sts;\r
515         int Pos;\r
516 \r
517         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
518         WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
519         Sts = NO;\r
520         for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
521         {\r
522                 if(SignalDbase[Pos].Async == Async)\r
523                 {\r
524                         MessageBox(GetMainHwnd(), "Async handle already registerd.", "FFFTP inner error", MB_OK);\r
525                         break;\r
526                 }\r
527         }\r
528         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
529         ReleaseMutex(hAsyncTblAccMutex);\r
530 \r
531         if(Pos == MAX_SIGNAL_ENTRY_DBASE)\r
532         {\r
533                 // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
534                 WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
535                 for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
536                 {\r
537                         if(SignalDbase[Pos].Async == 0)\r
538                         {\r
539 \r
540 //SetTaskMsg("############### Regist dbase (%d)", Pos);\r
541 \r
542                                 SignalDbase[Pos].Async = Async;\r
543                                 SignalDbase[Pos].Done = 0;\r
544                                 SignalDbase[Pos].ErrorDb = 0;\r
545                                 Sts = YES;\r
546                                 break;\r
547                         }\r
548                 }\r
549                 // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
550                 ReleaseMutex(hAsyncTblAccMutex);\r
551 \r
552                 if(Pos == MAX_SIGNAL_ENTRY_DBASE)\r
553                 {\r
554                         MessageBox(GetMainHwnd(), "No more async dbase regist space.", "FFFTP inner error", MB_OK);\r
555                         exit(1);\r
556                 }\r
557         }\r
558 \r
559         return(Sts);\r
560 }\r
561 \r
562 \r
563 /*----- \r
564 *\r
565 *       Parameter\r
566 *               \r
567 *\r
568 *       Return Value\r
569 *               \r
570 *----------------------------------------------------------------------------*/\r
571 \r
572 static int UnRegistAsyncTable(SOCKET s)\r
573 {\r
574         int Sts;\r
575         int Pos;\r
576 \r
577         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
578         WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
579         Sts = NO;\r
580         for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
581         {\r
582                 if(Signal[Pos].Socket == s)\r
583                 {\r
584 \r
585 //SetTaskMsg("############### UnRegist socket (%d)", Pos);\r
586 \r
587                         Signal[Pos].Socket = INVALID_SOCKET;\r
588                         Sts = YES;\r
589                         break;\r
590                 }\r
591         }\r
592         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
593         ReleaseMutex(hAsyncTblAccMutex);\r
594         return(Sts);\r
595 }\r
596 \r
597 \r
598 /*----- \r
599 *\r
600 *       Parameter\r
601 *               \r
602 *\r
603 *       Return Value\r
604 *               \r
605 *----------------------------------------------------------------------------*/\r
606 \r
607 static int UnRegistAsyncTableDbase(HANDLE Async)\r
608 {\r
609         int Sts;\r
610         int Pos;\r
611 \r
612         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
613         WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
614         Sts = NO;\r
615         for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
616         {\r
617                 if(SignalDbase[Pos].Async == Async)\r
618                 {\r
619 \r
620 //SetTaskMsg("############### UnRegist dbase (%d)", Pos);\r
621 \r
622                         SignalDbase[Pos].Async = 0;\r
623                         Sts = YES;\r
624                         break;\r
625                 }\r
626         }\r
627         // \83X\83\8c\83b\83h\8fÕ\93Ë\82Ì\83o\83O\8fC\90³\r
628         ReleaseMutex(hAsyncTblAccMutex);\r
629         return(Sts);\r
630 }\r
631 \r
632 \r
633 \r
634 \r
635 \r
636 \r
637 \r
638 \r
639 struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
640 {\r
641 #if USE_THIS\r
642         struct hostent *Ret;\r
643         HANDLE hAsync;\r
644         int Error;\r
645 \r
646 #if DBG_MSG\r
647         DoPrintf("# Start gethostbyname");\r
648 #endif\r
649         Ret = NULL;\r
650         *CancelCheckWork = NO;\r
651 \r
652         hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
653         if(hAsync != NULL)\r
654         {\r
655                 RegistAsyncTableDbase(hAsync);\r
656                 while((*CancelCheckWork == NO) && (AskAsyncDoneDbase(hAsync, &Error) != YES))\r
657                 {\r
658                         Sleep(1);\r
659                         if(BackgrndMessageProc() == YES)\r
660                                 *CancelCheckWork = YES;\r
661                 }\r
662 \r
663                 if(*CancelCheckWork == YES)\r
664                 {\r
665                         WSACancelAsyncRequest(hAsync);\r
666                 }\r
667                 else if(Error == 0)\r
668                 {\r
669                         Ret = (struct hostent *)Buf;\r
670                 }\r
671                 UnRegistAsyncTableDbase(hAsync);\r
672         }\r
673         return(Ret);\r
674 #else\r
675         return(gethostbyname(Name));\r
676 #endif\r
677 }\r
678 \r
679 \r
680 \r
681 \r
682 \r
683 SOCKET do_socket(int af, int type, int protocol)\r
684 {\r
685         SOCKET Ret;\r
686 \r
687         Ret = socket(af, type, protocol);\r
688         if(Ret != INVALID_SOCKET)\r
689         {\r
690                 RegistAsyncTable(Ret);\r
691         }\r
692 #if DBG_MSG\r
693         DoPrintf("# do_socket (S=%x)", Ret);\r
694 #endif\r
695         return(Ret);\r
696 }\r
697 \r
698 \r
699 \r
700 int do_closesocket(SOCKET s)\r
701 {\r
702 #if USE_THIS\r
703         int Ret;\r
704         int Error;\r
705         int CancelCheckWork;\r
706 \r
707 #if DBG_MSG\r
708         DoPrintf("# Start close (S=%x)", s);\r
709 #endif\r
710         CancelCheckWork = NO;\r
711 \r
712         // FTPS\91Î\89\9e\r
713 //      Ret = closesocket(s);\r
714         if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
715                 Ret = closesocketS(s);\r
716         else\r
717                 Ret = closesocket(s);\r
718         if(Ret == SOCKET_ERROR)\r
719         {\r
720                 Error = 0;\r
721                 while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE_BIT) != YES))\r
722                 {\r
723                         Sleep(1);\r
724                         if(BackgrndMessageProc() == YES)\r
725                                 CancelCheckWork = YES;\r
726                 }\r
727 \r
728                 if((CancelCheckWork == NO) && (Error == 0))\r
729                         Ret = 0;\r
730         }\r
731 \r
732         WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
733         if(BackgrndMessageProc() == YES)\r
734                 CancelCheckWork = YES;\r
735         UnRegistAsyncTable(s);\r
736 \r
737 #if DBG_MSG\r
738         DoPrintf("# Exit close");\r
739 #endif\r
740         return(Ret);\r
741 #else\r
742         return(closesocket(s));\r
743 #endif\r
744 }\r
745 \r
746 \r
747 \r
748 \r
749 \r
750 \r
751 int do_connect(SOCKET s, const struct sockaddr *name, int namelen, int *CancelCheckWork)\r
752 {\r
753 #if USE_THIS\r
754         int Ret;\r
755         int Error;\r
756 \r
757 #if DBG_MSG\r
758         DoPrintf("# Start connect (S=%x)", s);\r
759 #endif\r
760         *CancelCheckWork = NO;\r
761 \r
762 #if DBG_MSG\r
763         DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");\r
764 #endif\r
765         Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
766         if(Ret != SOCKET_ERROR)\r
767         {\r
768                 // FTPS\91Î\89\9e\r
769 //              Ret = connect(s, name, namelen);\r
770                 if(AskCryptMode() == CRYPT_FTPIS)\r
771                         Ret = connectS(s, name, namelen);\r
772                 else\r
773                         Ret = connect(s, name, namelen);\r
774                 if(Ret == SOCKET_ERROR)\r
775                 {\r
776                         do\r
777                         {\r
778                                 Error = 0;\r
779                                 while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT_BIT) != YES))\r
780                                 {\r
781                                         Sleep(1);\r
782                                         if(BackgrndMessageProc() == YES)\r
783                                                 *CancelCheckWork = YES;\r
784                                 }\r
785 \r
786                                 if(*CancelCheckWork == YES)\r
787                                         break;\r
788                                 if(Error == 0)\r
789                                         Ret = 0;\r
790                                 else\r
791                                 {\r
792 //                                      Error = WSAGetLastError();\r
793                                         DoPrintf("#### Connect: Error=%d", Error);\r
794                                 }\r
795                         }\r
796                         while((Ret != 0) && (Error == WSAEWOULDBLOCK));\r
797                 }\r
798         }\r
799         else\r
800                 DoPrintf("#### Connect: AsyncSelect error (%d)", WSAGetLastError());\r
801 \r
802 #if DBG_MSG\r
803         DoPrintf("# Exit connect (%d)", Ret);\r
804 #endif\r
805         return(Ret);\r
806 #else\r
807         return(connect(s, name, namelen));\r
808 #endif\r
809 }\r
810 \r
811 \r
812 \r
813 \r
814 \r
815 int do_listen(SOCKET s, int backlog)\r
816 {\r
817         int Ret;\r
818 \r
819         Ret = 1;\r
820 #if DBG_MSG\r
821         DoPrintf("# Start listen (S=%x)", s);\r
822         DoPrintf("## Async set: FD_CLOSE|FD_ACCEPT");\r
823 #endif\r
824 \r
825         Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CLOSE | FD_ACCEPT);\r
826         if(Ret != SOCKET_ERROR)\r
827                 Ret = listen(s, backlog);\r
828 \r
829 #if DBG_MSG\r
830         DoPrintf("# Exit listen (%d)", Ret);\r
831 #endif\r
832         return(Ret);\r
833 }\r
834 \r
835 \r
836 \r
837 SOCKET do_accept(SOCKET s, struct sockaddr *addr, int *addrlen)\r
838 {\r
839 #if USE_THIS\r
840         SOCKET Ret2;\r
841         int CancelCheckWork;\r
842         int Error;\r
843 \r
844 #if DBG_MSG\r
845         DoPrintf("# Start accept (S=%x)", s);\r
846 #endif\r
847         CancelCheckWork = NO;\r
848         Ret2 = INVALID_SOCKET;\r
849         Error = 0;\r
850 \r
851         while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT_BIT) != YES))\r
852         {\r
853                 if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
854                 {\r
855                         Error = 1;\r
856                         break;\r
857                 }\r
858                 Sleep(1);\r
859                 if(BackgrndMessageProc() == YES)\r
860                         CancelCheckWork = YES;\r
861         }\r
862 \r
863         if((CancelCheckWork == NO) && (Error == 0))\r
864         {\r
865                 do\r
866                 {\r
867                         // FTPS\91Î\89\9e\r
868 //                      Ret2 = accept(s, addr, addrlen);\r
869                         if(AskCryptMode() == CRYPT_FTPIS)\r
870                                 Ret2 = acceptS(s, addr, addrlen);\r
871                         else\r
872                                 Ret2 = accept(s, addr, addrlen);\r
873                         if(Ret2 != INVALID_SOCKET)\r
874                         {\r
875 #if DBG_MSG\r
876                                 DoPrintf("## do_sccept (S=%x)", Ret2);\r
877                                 DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");\r
878 #endif\r
879                                 RegistAsyncTable(Ret2);\r
880                                 if(WSAAsyncSelect(Ret2, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE) == SOCKET_ERROR)\r
881                                 {\r
882                                         do_closesocket(Ret2);\r
883                                         Ret2 = INVALID_SOCKET;\r
884                                 }\r
885                                 break;\r
886                         }\r
887                         Error = WSAGetLastError();\r
888                         Sleep(1);\r
889                         if(BackgrndMessageProc() == YES)\r
890                                 break;\r
891                 }\r
892                 while(Error == WSAEWOULDBLOCK);\r
893         }\r
894 \r
895 #if DBG_MSG\r
896         DoPrintf("# Exit accept");\r
897 #endif\r
898         return(Ret2);\r
899 #else\r
900         return(accept(s, addr, addrlen));\r
901 #endif\r
902 }\r
903 \r
904 \r
905 \r
906 \r
907 /*----- recv\91\8a\93\96\82Ì\8aÖ\90\94 --------------------------------------------------------\r
908 *\r
909 *       Parameter\r
910 *               SOCKET s : \83\\83P\83b\83g\r
911 *               char *buf : \83f\81[\83^\82ð\93Ç\82Ý\8d\9e\82Þ\83o\83b\83t\83@\r
912 *               int len : \92·\82³\r
913 *               int flags : recv\82É\97^\82¦\82é\83t\83\89\83O\r
914 *               int *TimeOutErr : \83^\83C\83\80\83A\83E\83g\82µ\82½\82©\82Ç\82¤\82©\82ð\95Ô\82·\83\8f\81[\83N\r
915 *\r
916 *       Return Value\r
917 *               int : recv\82Ì\96ß\82è\92l\82Æ\93¯\82\r
918 *\r
919 *       Note\r
920 *               \83^\83C\83\80\83A\83E\83g\82Ì\8e\9e\82Í TimeOut=YES\81ARet=SOCKET_ERROR \82É\82È\82é\r
921 *----------------------------------------------------------------------------*/\r
922 int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *CancelCheckWork)\r
923 {\r
924 #if USE_THIS\r
925         int Ret;\r
926         time_t StartTime;\r
927         time_t ElapseTime;\r
928         int Error;\r
929 \r
930 #if DBG_MSG\r
931         DoPrintf("# Start recv (S=%x)", s);\r
932 #endif\r
933         *TimeOutErr = NO;\r
934         *CancelCheckWork = NO;\r
935         Ret = SOCKET_ERROR;\r
936         Error = 0;\r
937 \r
938         if(TimeOut != 0)\r
939                 time(&StartTime);\r
940 \r
941         // FTPS\91Î\89\9e\r
942         // OpenSSL\82Å\82Í\8eó\90M\8am\94F\82ÍFD_READ\82ª\95¡\90\94\89ñ\8eó\90M\82³\82ê\82é\89Â\94\\90«\82ª\82 \82é\r
943 //      while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES))\r
944         while(AskCryptMode() == CRYPT_NONE && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES))\r
945         {\r
946                 if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
947                 {\r
948                         Ret = 0;\r
949                         break;\r
950                 }\r
951                 Sleep(1);\r
952                 if(BackgrndMessageProc() == YES)\r
953                         *CancelCheckWork = YES;\r
954                 else if(TimeOut != 0)\r
955                 {\r
956                         time(&ElapseTime);\r
957                         ElapseTime -= StartTime;\r
958                         if(ElapseTime >= TimeOut)\r
959                         {\r
960                                 DoPrintf("do_recv timed out");\r
961                                 *TimeOutErr = YES;\r
962                                 *CancelCheckWork = YES;\r
963                         }\r
964                 }\r
965         }\r
966 \r
967         if(/*(Ret != 0) && */(Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO))\r
968         {\r
969                 do\r
970                 {\r
971 #if DBG_MSG\r
972                         DoPrintf("## recv()");\r
973 #endif\r
974 \r
975                         // FTPS\91Î\89\9e\r
976 //                      Ret = recv(s, buf, len, flags);\r
977                         if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
978                                 Ret = recvS(s, buf, len, flags);\r
979                         else\r
980                                 Ret = recv(s, buf, len, flags);\r
981                         if(Ret != SOCKET_ERROR)\r
982                                 break;\r
983                         Error = WSAGetLastError();\r
984                         Sleep(1);\r
985                         if(BackgrndMessageProc() == YES)\r
986                                 break;\r
987                         // FTPS\91Î\89\9e\r
988                         // \8eó\90M\8am\94F\82ð\83o\83C\83p\83X\82µ\82½\82½\82ß\82±\82±\82Å\83^\83C\83\80\83A\83E\83g\82Ì\8am\94F\r
989                         if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
990                         {\r
991                                 if(BackgrndMessageProc() == YES)\r
992                                         *CancelCheckWork = YES;\r
993                         }\r
994                         else if(TimeOut != 0)\r
995                         {\r
996                                 time(&ElapseTime);\r
997                                 ElapseTime -= StartTime;\r
998                                 if(ElapseTime >= TimeOut)\r
999                                 {\r
1000                                         DoPrintf("do_recv timed out");\r
1001                                         *TimeOutErr = YES;\r
1002                                         *CancelCheckWork = YES;\r
1003                                 }\r
1004                         }\r
1005                         if(*CancelCheckWork == YES)\r
1006                                 break;\r
1007                 }\r
1008                 while(Error == WSAEWOULDBLOCK);\r
1009         }\r
1010 \r
1011         if(BackgrndMessageProc() == YES)\r
1012                 Ret = SOCKET_ERROR;\r
1013 \r
1014 #if DBG_MSG\r
1015         DoPrintf("# Exit recv (%d)", Ret);\r
1016 #endif\r
1017         return(Ret);\r
1018 #else\r
1019         return(recv(s, buf, len, flags));\r
1020 #endif\r
1021 }\r
1022 \r
1023 \r
1024 \r
1025 int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int *CancelCheckWork)\r
1026 {\r
1027 #if USE_THIS\r
1028         int Ret;\r
1029         time_t StartTime;\r
1030         time_t ElapseTime;\r
1031         int Error;\r
1032 \r
1033 #if DBG_MSG\r
1034         DoPrintf("# Start send (S=%x)", s);\r
1035 #endif\r
1036         *TimeOutErr = NO;\r
1037         *CancelCheckWork = NO;\r
1038         Ret = SOCKET_ERROR;\r
1039         Error = 0;\r
1040 \r
1041         if(TimeOut != 0)\r
1042                 time(&StartTime);\r
1043 \r
1044 #if DBG_MSG\r
1045         DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");\r
1046 #endif\r
1047         WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
1048         if(BackgrndMessageProc() == YES)\r
1049                 *CancelCheckWork = YES;\r
1050 \r
1051         // FTPS\91Î\89\9e\r
1052         // \91\97\90M\83o\83b\83t\83@\82Ì\8bó\82«\8am\94F\82É\82Í\89e\8b¿\82µ\82È\82¢\82ª\94O\82Ì\82½\82ß\r
1053 //      while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))\r
1054         while(AskCryptMode() == CRYPT_NONE && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))\r
1055         {\r
1056                 if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
1057                 {\r
1058                         Error = 1;\r
1059                         break;\r
1060                 }\r
1061 \r
1062                 Sleep(1);\r
1063                 if(BackgrndMessageProc() == YES)\r
1064                         *CancelCheckWork = YES;\r
1065                 else if(TimeOut != 0)\r
1066                 {\r
1067                         time(&ElapseTime);\r
1068                         ElapseTime -= StartTime;\r
1069                         if(ElapseTime >= TimeOut)\r
1070                         {\r
1071                                 DoPrintf("do_write timed out");\r
1072                                 *TimeOutErr = YES;\r
1073                                 *CancelCheckWork = YES;\r
1074                         }\r
1075                 }\r
1076         }\r
1077 \r
1078         if((Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO))\r
1079         {\r
1080                 do\r
1081                 {\r
1082 #if DBG_MSG\r
1083                         DoPrintf("## send()");\r
1084 #endif\r
1085 \r
1086                         // FTPS\91Î\89\9e\r
1087 //                      Ret = send(s, buf, len, flags);\r
1088                         if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
1089                                 Ret = sendS(s, buf, len, flags);\r
1090                         else\r
1091                                 Ret = send(s, buf, len, flags);\r
1092                         if(Ret != SOCKET_ERROR)\r
1093                         {\r
1094 #if DBG_MSG\r
1095                                 DoPrintf("## send() OK");\r
1096 #endif\r
1097                                 break;\r
1098                         }\r
1099                         Error = WSAGetLastError();\r
1100                         Sleep(1);\r
1101                         if(BackgrndMessageProc() == YES)\r
1102                                 break;\r
1103                         // FTPS\91Î\89\9e\r
1104                         // \91\97\90M\83o\83b\83t\83@\8am\94F\82ð\83o\83C\83p\83X\82µ\82½\82½\82ß\82±\82±\82Å\83^\83C\83\80\83A\83E\83g\82Ì\8am\94F\r
1105                         if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
1106                         {\r
1107                                 if(BackgrndMessageProc() == YES)\r
1108                                         *CancelCheckWork = YES;\r
1109                         }\r
1110                         else if(TimeOut != 0)\r
1111                         {\r
1112                                 time(&ElapseTime);\r
1113                                 ElapseTime -= StartTime;\r
1114                                 if(ElapseTime >= TimeOut)\r
1115                                 {\r
1116                                         DoPrintf("do_recv timed out");\r
1117                                         *TimeOutErr = YES;\r
1118                                         *CancelCheckWork = YES;\r
1119                                 }\r
1120                         }\r
1121                         if(*CancelCheckWork == YES)\r
1122                                 break;\r
1123                 }\r
1124                 while(Error == WSAEWOULDBLOCK);\r
1125         }\r
1126 \r
1127         if(BackgrndMessageProc() == YES)\r
1128                 Ret = SOCKET_ERROR;\r
1129 \r
1130 #if DBG_MSG\r
1131         DoPrintf("# Exit send (%d)", Ret);\r
1132 #endif\r
1133         return(Ret);\r
1134 #else\r
1135         return(send(s, buf, len, flags));\r
1136 #endif\r
1137 }\r
1138 \r
1139 \r
1140 /*----- \r
1141 *\r
1142 *       Parameter\r
1143 *\r
1144 *       Return Value\r
1145 *               int \83X\83e\81[\83^\83X\r
1146 *                       SUCCESS/FAIL\r
1147 *----------------------------------------------------------------------------*/\r
1148 \r
1149 int CheckClosedAndReconnect(void)\r
1150 {\r
1151         int Error;\r
1152         int Sts;\r
1153 \r
1154 //SetTaskMsg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");\r
1155 \r
1156         Sts = SUCCESS;\r
1157         if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE_BIT) == YES)\r
1158         {\r
1159                 Sts = ReConnectCmdSkt();\r
1160         }\r
1161         return(Sts);\r
1162 }\r
1163 \r
1164 \r
1165 \r