OSDN Git Service

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