OSDN Git Service

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