Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ttcomtester/teraterm/teraterm/commlib.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3968 - (hide annotations) (download) (as text)
Thu Aug 5 16:07:10 2010 UTC (13 years, 8 months ago) by yutakapon
Original Path: trunk/teraterm/teraterm/commlib.c
File MIME type: text/x-csrc
File size: 28913 byte(s)
ソケットの二重クローズをしないようにした。

1 maya 3857 /* Tera Term
2     Copyright(C) 1994-1998 T. Teranishi
3     All rights reserved. */
4     /* IPv6 modification is Copyright (C) 2000, 2001 Jun-ya KATO <kato@win6.jp> */
5    
6     /* TERATERM.EXE, Communication routines */
7     #include "teraterm.h"
8     #include "tttypes.h"
9     #include "tt_res.h"
10     #include <process.h>
11    
12     #include "ttcommon.h"
13     #include "ttwsk.h"
14     #include "ttlib.h"
15     #include "ttfileio.h"
16     #include "ttplug.h" /* TTPLUG */
17    
18     #include "commlib.h"
19     #ifndef NO_INET6
20     #include <winsock2.h>
21     #include <ws2tcpip.h>
22     #include <stdio.h> /* for _snprintf() */
23     #include "WSAAsyncGetAddrInfo.h"
24     #endif /* NO_INET6 */
25     #include <time.h>
26 doda 3932 #include <locale.h>
27 maya 3857
28     static SOCKET OpenSocket(PComVar);
29     static void AsyncConnect(PComVar);
30     static int CloseSocket(SOCKET);
31    
32     /* create socket */
33     static SOCKET OpenSocket(PComVar cv)
34     {
35     cv->s = cv->res->ai_family;
36     cv->s = Psocket(cv->res->ai_family, cv->res->ai_socktype, cv->res->ai_protocol);
37     return cv->s;
38     }
39    
40     /* connect with asynchronous mode */
41     static void AsyncConnect(PComVar cv)
42     {
43     int Err;
44     BOOL BBuf;
45     BBuf = TRUE;
46     /* set synchronous mode */
47     PWSAAsyncSelect(cv->s,cv->HWin,0,0);
48     Psetsockopt(cv->s,(int)SOL_SOCKET,SO_OOBINLINE,(char FAR *)&BBuf,sizeof(BBuf));
49     /* set asynchronous mode */
50     PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMOPEN, FD_CONNECT);
51    
52     // �z�X�g���������������������������A�����I���\�P�b�g���N���[�Y�����A
53     // �����������L�����Z���������B�l��0�������������������B
54     // (2007.1.11 yutaka)
55     if (*cv->ConnetingTimeout > 0) {
56     SetTimer(cv->HWin, IdCancelConnectTimer, *cv->ConnetingTimeout * 1000, NULL);
57     }
58    
59     /* WM_USER_COMMOPEN occurs, CommOpen is called, then CommStart is called */
60     Err = Pconnect(cv->s, cv->res->ai_addr, cv->res->ai_addrlen);
61     if (Err != 0) {
62     Err = PWSAGetLastError();
63     if (Err == WSAEWOULDBLOCK) {
64     /* Do nothing */
65     } else if (Err!=0 ) {
66     PostMessage(cv->HWin, WM_USER_COMMOPEN,0,
67     MAKELONG(FD_CONNECT,Err));
68     }
69     }
70     }
71    
72     /* close socket */
73     static int CloseSocket(SOCKET s)
74     {
75     return Pclosesocket(s);
76     }
77    
78     #define CommInQueSize 8192
79     #define CommOutQueSize 2048
80     #define CommXonLim 2048
81     #define CommXoffLim 2048
82    
83     #define READENDNAME "ReadEnd"
84     #define WRITENAME "Write"
85     #define READNAME "Read"
86     #define PRNWRITENAME "PrnWrite"
87    
88     static HANDLE ReadEnd;
89     static OVERLAPPED wol, rol;
90    
91     // Winsock async operation handle
92     static HANDLE HAsync=0;
93    
94     BOOL TCPIPClosed = TRUE;
95    
96     /* Printer port handle for
97     direct pass-thru printing */
98     static HANDLE PrnID = INVALID_HANDLE_VALUE;
99     static BOOL LPTFlag;
100    
101     // Initialize ComVar.
102     // This routine is called only once
103     // by the initialization procedure of Tera Term.
104     void CommInit(PComVar cv)
105     {
106     cv->Open = FALSE;
107     cv->Ready = FALSE;
108    
109     // log-buffer variables
110     cv->HLogBuf = 0;
111     cv->HBinBuf = 0;
112     cv->LogBuf = NULL;
113     cv->BinBuf = NULL;
114     cv->LogPtr = 0;
115     cv->LStart = 0;
116     cv->LCount = 0;
117     cv->BinPtr = 0;
118     cv->BStart = 0;
119     cv->BCount = 0;
120     cv->DStart = 0;
121     cv->DCount = 0;
122     cv->BinSkip = 0;
123     cv->FilePause = 0;
124     cv->ProtoFlag = FALSE;
125     /* message flag */
126     cv->NoMsg = 0;
127     }
128    
129     /* reset a serial port which is already open */
130     void CommResetSerial(PTTSet ts, PComVar cv, BOOL ClearBuff)
131     {
132     DCB dcb;
133     DWORD DErr;
134     COMMTIMEOUTS ctmo;
135    
136     if (! cv->Open ||
137     (cv->PortType != IdSerial)) {
138     return;
139     }
140    
141     ClearCommError(cv->ComID,&DErr,NULL);
142     SetupComm(cv->ComID,CommInQueSize,CommOutQueSize);
143     /* flush input and output buffers */
144     if (ClearBuff) {
145     PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT |
146     PURGE_TXCLEAR | PURGE_RXCLEAR);
147     }
148    
149     memset(&ctmo,0,sizeof(ctmo));
150     ctmo.ReadIntervalTimeout = MAXDWORD;
151     ctmo.WriteTotalTimeoutConstant = 500;
152     SetCommTimeouts(cv->ComID,&ctmo);
153     cv->InBuffCount = 0;
154     cv->InPtr = 0;
155     cv->OutBuffCount = 0;
156     cv->OutPtr = 0;
157    
158     cv->DelayPerChar = ts->DelayPerChar;
159     cv->DelayPerLine = ts->DelayPerLine;
160    
161     memset(&dcb,0,sizeof(DCB));
162     dcb.DCBlength = sizeof(DCB);
163 maya 3874 dcb.BaudRate = ts->Baud;
164 maya 3857 dcb.fBinary = TRUE;
165     switch (ts->Parity) {
166     case IdParityEven:
167     dcb.fParity = TRUE;
168     dcb.Parity = EVENPARITY;
169     break;
170     case IdParityOdd:
171     dcb.fParity = TRUE;
172     dcb.Parity = ODDPARITY;
173     break;
174     case IdParityNone:
175     dcb.Parity = NOPARITY;
176     break;
177     }
178    
179     dcb.fDtrControl = DTR_CONTROL_ENABLE;
180     dcb.fRtsControl = RTS_CONTROL_ENABLE;
181     switch (ts->Flow) {
182     case IdFlowX:
183     dcb.fOutX = TRUE;
184     dcb.fInX = TRUE;
185     dcb.XonLim = CommXonLim;
186     dcb.XoffLim = CommXoffLim;
187     dcb.XonChar = XON;
188     dcb.XoffChar = XOFF;
189     break;
190     case IdFlowHard:
191     dcb.fOutxCtsFlow = TRUE;
192     dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
193     break;
194     }
195    
196     switch (ts->DataBit) {
197     case IdDataBit7:
198     dcb.ByteSize = 7;
199     break;
200     case IdDataBit8:
201     dcb.ByteSize = 8;
202     break;
203     }
204     switch (ts->StopBit) {
205     case IdStopBit1:
206     dcb.StopBits = ONESTOPBIT;
207     break;
208     case IdStopBit2:
209     dcb.StopBits = TWOSTOPBITS;
210     break;
211     }
212    
213     SetCommState(cv->ComID, &dcb);
214    
215     /* enable receive request */
216     SetCommMask(cv->ComID,0);
217     SetCommMask(cv->ComID,EV_RXCHAR);
218     }
219    
220     void CommOpen(HWND HW, PTTSet ts, PComVar cv)
221     {
222     #ifdef NO_INET6
223     int Err;
224     #endif /* NO_INET6 */
225     char ErrMsg[21];
226     char P[50];
227    
228     MSG Msg;
229     #ifndef NO_INET6
230     ADDRINFO hints;
231     char pname[NI_MAXSERV];
232     #else
233     char HEntBuff[MAXGETHOSTSTRUCT];
234     u_long addr;
235     SOCKADDR_IN saddr;
236     #endif /* NO_INET6 */
237    
238     BOOL InvalidHost;
239     #ifdef NO_INET6
240     BOOL BBuf;
241     #endif /* NO_INET6 */
242    
243     char uimsg[MAX_UIMSG];
244    
245     /* initialize ComVar */
246     cv->InBuffCount = 0;
247     cv->InPtr = 0;
248     cv->OutBuffCount = 0;
249     cv->OutPtr = 0;
250     cv->HWin = HW;
251     cv->Ready = FALSE;
252     cv->Open = FALSE;
253     cv->PortType = ts->PortType;
254     cv->ComPort = 0;
255     cv->RetryCount = 0;
256     #ifndef NO_INET6
257     cv->RetryWithOtherProtocol = TRUE;
258     #endif /* NO_INET6 */
259     cv->s = INVALID_SOCKET;
260     cv->ComID = INVALID_HANDLE_VALUE;
261     cv->CanSend = TRUE;
262     cv->RRQ = FALSE;
263     cv->SendKanjiFlag = FALSE;
264     cv->SendCode = IdASCII;
265     cv->EchoKanjiFlag = FALSE;
266     cv->EchoCode = IdASCII;
267     cv->Language = ts->Language;
268     cv->CRSend = ts->CRSend;
269     cv->KanjiCodeEcho = ts->KanjiCode;
270     cv->JIS7KatakanaEcho = ts->JIS7Katakana;
271     cv->KanjiCodeSend = ts->KanjiCodeSend;
272     cv->JIS7KatakanaSend = ts->JIS7KatakanaSend;
273     cv->KanjiIn = ts->KanjiIn;
274     cv->KanjiOut = ts->KanjiOut;
275     cv->RussHost = ts->RussHost;
276     cv->RussClient = ts->RussClient;
277     cv->DelayFlag = TRUE;
278     cv->DelayPerChar = ts->DelayPerChar;
279     cv->DelayPerLine = ts->DelayPerLine;
280     cv->TelBinRecv = FALSE;
281     cv->TelBinSend = FALSE;
282     cv->TelFlag = FALSE;
283     cv->TelMode = FALSE;
284     cv->IACFlag = FALSE;
285     cv->TelCRFlag = FALSE;
286     cv->TelCRSend = FALSE;
287     cv->TelCRSendEcho = FALSE;
288     cv->TelAutoDetect = ts->TelAutoDetect; /* TTPLUG */
289     cv->Locale = ts->Locale;
290 doda 3932 cv->locale = _create_locale(LC_ALL, cv->Locale);
291 maya 3857 cv->CodePage = &ts->CodePage;
292     cv->ConnetingTimeout = &ts->ConnectingTimeout;
293     cv->LastSendTime = time(NULL);
294     cv->LineModeBuffCount = 0;
295     cv->Flush = FALSE;
296     cv->FlushLen = 0;
297     cv->TelLineMode = FALSE;
298 yutakapon 3926 cv->pureutf8 = &ts->pureutf8;
299 maya 3857
300     if ((ts->PortType!=IdSerial) && (strlen(ts->HostName)==0))
301     {
302     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
303     return;
304     }
305    
306     switch (ts->PortType) {
307     case IdTCPIP:
308     cv->TelFlag = (ts->Telnet > 0);
309     if (ts->EnableLineMode) {
310     cv->TelLineMode = TRUE;
311     }
312     if (! LoadWinsock()) {
313     if (cv->NoMsg==0) {
314     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
315     get_lang_msg("MSG_WINSOCK_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot use winsock", ts->UILanguageFile);
316     MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
317     }
318     InvalidHost = TRUE;
319     }
320     else {
321     TTXOpenTCP(); /* TTPLUG */
322     cv->Open = TRUE;
323     #ifndef NO_INET6
324     /* resolving address */
325     memset(&hints, 0, sizeof(hints));
326     hints.ai_family = ts->ProtocolFamily;
327     hints.ai_socktype = SOCK_STREAM;
328     hints.ai_protocol = IPPROTO_TCP;
329     _snprintf_s(pname, sizeof(pname), _TRUNCATE, "%d", ts->TCPPort);
330    
331     HAsync = WSAAsyncGetAddrInfo(HW, WM_USER_GETHOST,
332     ts->HostName, pname, &hints, &cv->res0);
333     if (HAsync == 0)
334     InvalidHost = TRUE;
335     else {
336     cv->ComPort = 1; // set "getting host" flag
337     // (see CVTWindow::OnSysCommand())
338     do {
339     if (GetMessage(&Msg,0,0,0)) {
340     if ((Msg.hwnd==HW) &&
341     ((Msg.message == WM_SYSCOMMAND) &&
342     ((Msg.wParam & 0xfff0) == SC_CLOSE) ||
343     (Msg.message == WM_COMMAND) &&
344     (LOWORD(Msg.wParam) == ID_FILE_EXIT) ||
345     (Msg.message == WM_CLOSE))) { /* Exit when the user closes Tera Term */
346     PWSACancelAsyncRequest(HAsync);
347     CloseHandle(HAsync);
348     HAsync = 0;
349     cv->ComPort = 0; // clear "getting host" flag
350     PostMessage(HW,Msg.message,Msg.wParam,Msg.lParam);
351     return;
352     }
353     if (Msg.message != WM_USER_GETHOST) { /* Prosess messages */
354     TranslateMessage(&Msg);
355     DispatchMessage(&Msg);
356     }
357     }
358     else {
359     return;
360     }
361     } while (Msg.message!=WM_USER_GETHOST);
362     cv->ComPort = 0; // clear "getting host" flag
363     CloseHandle(HAsync);
364     HAsync = 0;
365     InvalidHost = WSAGETASYNCERROR(Msg.lParam) != 0;
366     }
367     } /* if (!LoadWinsock()) */
368    
369     if (InvalidHost) {
370     if (cv->NoMsg==0) {
371     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
372     get_lang_msg("MSG_INVALID_HOST_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Invalid host", ts->UILanguageFile);
373     MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
374     }
375     goto BreakSC;
376     }
377     for (cv->res = cv->res0; cv->res; cv->res = cv->res->ai_next) {
378     cv->s = OpenSocket(cv);
379     if (cv->s == INVALID_SOCKET) {
380     CloseSocket(cv->s);
381     continue;
382     }
383     /* start asynchronous connect */
384     AsyncConnect(cv);
385     break; /* break for-loop immediately */
386     }
387     break;
388     #else
389     if ((ts->HostName[0] >= 0x30) && (ts->HostName[0] <= 0x39))
390     {
391     addr = Pinet_addr(ts->HostName);
392     InvalidHost = (addr == 0xffffffff);
393     }
394     else {
395     HAsync = PWSAAsyncGetHostByName(HW,WM_USER_GETHOST,
396     ts->HostName,HEntBuff,sizeof(HEntBuff));
397     if (HAsync == 0)
398     InvalidHost = TRUE;
399     else {
400     cv->ComPort = 1; // set "getting host" flag
401     // (see CVTWindow::OnSysCommand())
402     do {
403     if (GetMessage(&Msg,0,0,0))
404     {
405     if ((Msg.hwnd==HW) &&
406     ((Msg.message == WM_SYSCOMMAND) &&
407     ((Msg.wParam & 0xfff0) == SC_CLOSE) ||
408     (Msg.message == WM_COMMAND) &&
409     (LOWORD(Msg.wParam) == ID_FILE_EXIT) ||
410     (Msg.message == WM_CLOSE)))
411     { /* Exit when the user closes Tera Term */
412     PWSACancelAsyncRequest(HAsync);
413     HAsync = 0;
414     cv->ComPort = 0; // clear "getting host" flag
415     PostMessage(HW,Msg.message,Msg.wParam,Msg.lParam);
416     return;
417     }
418     if (Msg.message != WM_USER_GETHOST)
419     { /* Prosess messages */
420     TranslateMessage(&Msg);
421     DispatchMessage(&Msg);
422     }
423     }
424     else {
425     return;
426     }
427     } while (Msg.message!=WM_USER_GETHOST);
428     cv->ComPort = 0; // clear "getting host" flag
429     HAsync = 0;
430     InvalidHost = WSAGETASYNCERROR(Msg.lParam) != 0;
431     if (! InvalidHost)
432     {
433     if (((PHOSTENT)HEntBuff)->h_addr_list != NULL)
434     memcpy(&addr,
435     ((PHOSTENT)HEntBuff)->h_addr_list[0],sizeof(addr));
436     else
437     InvalidHost = TRUE;
438     }
439     }
440    
441     }
442    
443     if (InvalidHost)
444     {
445     if (cv->NoMsg==0)
446     MessageBox(cv->HWin,"Invalid host",ErrorCaption,
447     MB_TASKMODAL | MB_ICONEXCLAMATION);
448     }
449     else {
450     cv->s= Psocket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
451     if (cv->s==INVALID_SOCKET)
452     {
453     InvalidHost = TRUE;
454     if (cv->NoMsg==0)
455     MessageBox(cv->HWin,ErrorCantConn,ErrorCaption,
456     MB_TASKMODAL | MB_ICONEXCLAMATION);
457     }
458     else {
459     BBuf = TRUE;
460     Psetsockopt(cv->s,(int)SOL_SOCKET,SO_OOBINLINE,(char FAR *)&BBuf,sizeof(BBuf));
461    
462     PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMOPEN, FD_CONNECT);
463     saddr.sin_family = AF_INET;
464     saddr.sin_port = Phtons(ts->TCPPort);
465     saddr.sin_addr.s_addr = addr;
466     memset(saddr.sin_zero,0,8);
467    
468     Err = Pconnect(cv->s,(LPSOCKADDR)&saddr,sizeof(saddr));
469     if (Err!=0 ) Err = PWSAGetLastError();
470     if (Err==WSAEWOULDBLOCK )
471     {
472     /* Do nothing */
473     }
474     else if (Err!=0 )
475     PostMessage(cv->HWin, WM_USER_COMMOPEN,0,
476     MAKELONG(FD_CONNECT,Err));
477     }
478     }
479     }
480     break;
481     #endif /* NO_INET6 */
482    
483     case IdSerial:
484     InitFileIO(IdSerial); /* TTPLUG */
485     TTXOpenFile(); /* TTPLUG */
486     _snprintf_s(P, sizeof(P), _TRUNCATE, "COM%d", ts->ComPort);
487     strncpy_s(ErrMsg, sizeof(ErrMsg),P, _TRUNCATE);
488     strncpy_s(P, sizeof(P),"\\\\.\\", _TRUNCATE);
489     strncat_s(P, sizeof(P),ErrMsg, _TRUNCATE);
490     cv->ComID =
491     PCreateFile(P,GENERIC_READ | GENERIC_WRITE,
492     0,NULL,OPEN_EXISTING,
493     FILE_FLAG_OVERLAPPED,NULL);
494     if (cv->ComID == INVALID_HANDLE_VALUE ) {
495     get_lang_msg("MSG_CANTOEPN_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s", ts->UILanguageFile);
496     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4]);
497    
498     if (cv->NoMsg==0) {
499     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
500     MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
501     }
502     InvalidHost = TRUE;
503     }
504     else {
505     cv->Open = TRUE;
506     cv->ComPort = ts->ComPort;
507     CommResetSerial(ts, cv, ts->ClearComBuffOnOpen);
508     if (!ts->ClearComBuffOnOpen) {
509     cv->RRQ = TRUE;
510     }
511    
512     /* notify to VT window that Comm Port is open */
513     PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);
514     InvalidHost = FALSE;
515    
516     SetCOMFlag(ts->ComPort);
517     }
518     break; /* end of "case IdSerial:" */
519    
520     case IdFile:
521     InitFileIO(IdFile); /* TTPLUG */
522     TTXOpenFile(); /* TTPLUG */
523     cv->ComID = PCreateFile(ts->HostName,GENERIC_READ,0,NULL,
524     OPEN_EXISTING,0,NULL);
525     InvalidHost = (cv->ComID == INVALID_HANDLE_VALUE);
526     if (InvalidHost) {
527     if (cv->NoMsg==0) {
528     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
529     get_lang_msg("MSG_CANTOEPN_FILE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open file", ts->UILanguageFile);
530     MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
531     }
532     }
533     else {
534     cv->Open = TRUE;
535     PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);
536     }
537     break;
538     } /* end of "switch" */
539    
540     #ifndef NO_INET6
541     BreakSC:
542     #endif /* NO_INET6 */
543     if (InvalidHost) {
544     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
545     if ( (ts->PortType==IdTCPIP) && cv->Open ) {
546     if ( cv->s!=INVALID_SOCKET ) {
547     Pclosesocket(cv->s);
548 yutakapon 3968 cv->s = INVALID_SOCKET; /* �\�P�b�g�����������t�����B(2010.8.6 yutaka) */
549 maya 3857 }
550     FreeWinsock();
551     }
552     return;
553     }
554     }
555    
556     void CommThread(void *arg)
557     {
558     DWORD Evt;
559     PComVar cv = (PComVar)arg;
560     DWORD DErr;
561     HANDLE REnd;
562     char Temp[20];
563    
564     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
565     REnd = OpenEvent(EVENT_ALL_ACCESS,FALSE, Temp);
566     while (TRUE) {
567     if (WaitCommEvent(cv->ComID,&Evt,NULL)) {
568     if (! cv->Ready) {
569     _endthread();
570     }
571     if (! cv->RRQ) {
572     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_READ);
573     }
574     WaitForSingleObject(REnd,INFINITE);
575     }
576     else {
577     DErr = GetLastError(); // this returns 995 (operation aborted) if a USB com port is removed
578     if (! cv->Ready || ERROR_OPERATION_ABORTED == DErr) {
579     _endthread();
580     }
581     ClearCommError(cv->ComID,&DErr,NULL);
582     }
583     }
584     }
585    
586     void CommStart(PComVar cv, LONG lParam, PTTSet ts)
587     {
588     char ErrMsg[31];
589     char Temp[20];
590     char uimsg[MAX_UIMSG];
591    
592     if (! cv->Open ) {
593     return;
594     }
595     if ( cv->Ready ) {
596     return;
597     }
598    
599     // �L�����Z���^�C�}�����������������B�������A�������_�� WM_TIMER �����������������\���������B
600     if (*cv->ConnetingTimeout > 0) {
601     KillTimer(cv->HWin, IdCancelConnectTimer);
602     }
603    
604     switch (cv->PortType) {
605     case IdTCPIP:
606     ErrMsg[0] = 0;
607     switch (HIWORD(lParam)) {
608     case WSAECONNREFUSED:
609     get_lang_msg("MSG_COMM_REFUSE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection refused", ts->UILanguageFile);
610     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
611     break;
612     case WSAENETUNREACH:
613     get_lang_msg("MSG_COMM_REACH_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Network cannot be reached", ts->UILanguageFile);
614     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
615     break;
616     case WSAETIMEDOUT:
617     get_lang_msg("MSG_COMM_CONNECT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection timed out", ts->UILanguageFile);
618     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
619     break;
620     default:
621     get_lang_msg("MSG_COMM_TIMEOUT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot connect the host", ts->UILanguageFile);
622     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
623     }
624     if (HIWORD(lParam)>0) {
625     #ifndef NO_INET6
626     /* connect() failed */
627     if (cv->res->ai_next != NULL) {
628     /* try to connect with other protocol */
629     CloseSocket(cv->s);
630     for (cv->res = cv->res->ai_next; cv->res; cv->res = cv->res->ai_next) {
631     cv->s = OpenSocket(cv);
632     if (cv->s == INVALID_SOCKET) {
633     CloseSocket(cv->s);
634     continue;
635     }
636     AsyncConnect(cv);
637     cv->Ready = FALSE;
638     cv->RetryWithOtherProtocol = TRUE; /* retry with other procotol */
639     return;
640     }
641     } else {
642     /* trying with all protocol family are failed */
643     if (cv->NoMsg==0)
644     {
645     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
646     MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
647     }
648     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
649     cv->RetryWithOtherProtocol = FALSE;
650     return;
651     }
652     #else
653     if (cv->NoMsg==0)
654     MessageBox(cv->HWin,ErrMsg,ErrorCaption,
655     MB_TASKMODAL | MB_ICONEXCLAMATION);
656     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
657     return;
658     #endif /* NO_INET6 */
659     }
660    
661     #ifndef NO_INET6
662     /* here is connection established */
663     cv->RetryWithOtherProtocol = FALSE;
664     #endif /* NO_INET6 */
665     PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_READ | FD_OOB | FD_CLOSE);
666     TCPIPClosed = FALSE;
667     break;
668    
669     case IdSerial:
670     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
671     ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp);
672     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort);
673     memset(&wol,0,sizeof(OVERLAPPED));
674     wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp);
675     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort);
676     memset(&rol,0,sizeof(OVERLAPPED));
677     rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp);
678    
679     /* create the receiver thread */
680     if (_beginthread(CommThread,0,cv) == -1) {
681     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
682     get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile);
683     MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
684     }
685     break;
686    
687     case IdFile:
688     cv->RRQ = TRUE;
689     break;
690     }
691     cv->Ready = TRUE;
692     }
693    
694     BOOL CommCanClose(PComVar cv)
695     { // check if data remains in buffer
696     if (! cv->Open) {
697     return TRUE;
698     }
699     if (cv->InBuffCount>0) {
700     return FALSE;
701     }
702     if ((cv->HLogBuf!=NULL) &&
703     ((cv->LCount>0) ||
704     (cv->DCount>0))) {
705     return FALSE;
706     }
707     if ((cv->HBinBuf!=NULL) &&
708     (cv->BCount>0)) {
709     return FALSE;
710     }
711     return TRUE;
712     }
713    
714     void CommClose(PComVar cv)
715     {
716     if ( ! cv->Open ) {
717     return;
718     }
719     cv->Open = FALSE;
720    
721     /* disable event message posting & flush buffer */
722     cv->RRQ = FALSE;
723     cv->Ready = FALSE;
724     cv->InPtr = 0;
725     cv->InBuffCount = 0;
726     cv->OutPtr = 0;
727     cv->OutBuffCount = 0;
728     cv->LineModeBuffCount = 0;
729     cv->FlushLen = 0;
730     cv->Flush = FALSE;
731    
732     /* close port & release resources */
733     switch (cv->PortType) {
734     case IdTCPIP:
735     if (HAsync!=0) {
736     PWSACancelAsyncRequest(HAsync);
737     }
738     HAsync = 0;
739     #ifndef NO_INET6
740     freeaddrinfo(cv->res0);
741     #endif /* NO_INET6 */
742     if ( cv->s!=INVALID_SOCKET ) {
743     Pclosesocket(cv->s);
744     }
745     cv->s = INVALID_SOCKET;
746     TTXCloseTCP(); /* TTPLUG */
747     FreeWinsock();
748     break;
749     case IdSerial:
750     if ( cv->ComID != INVALID_HANDLE_VALUE ) {
751     CloseHandle(ReadEnd);
752     CloseHandle(wol.hEvent);
753     CloseHandle(rol.hEvent);
754     PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT |
755     PURGE_TXCLEAR | PURGE_RXCLEAR);
756     EscapeCommFunction(cv->ComID,CLRDTR);
757     SetCommMask(cv->ComID,0);
758     PCloseFile(cv->ComID);
759     ClearCOMFlag(cv->ComPort);
760     }
761     TTXCloseFile(); /* TTPLUG */
762     break;
763     case IdFile:
764     if (cv->ComID != INVALID_HANDLE_VALUE) {
765     PCloseFile(cv->ComID);
766     }
767     TTXCloseFile(); /* TTPLUG */
768     break;
769     }
770     cv->ComID = INVALID_HANDLE_VALUE;
771     cv->PortType = 0;
772 doda 3932
773     _free_locale(cv->locale);
774 maya 3857 }
775    
776     void CommProcRRQ(PComVar cv)
777     {
778     if ( ! cv->Ready ) {
779     return;
780     }
781     /* disable receive request */
782     switch (cv->PortType) {
783     case IdTCPIP:
784     if (! TCPIPClosed) {
785     PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_OOB | FD_CLOSE);
786     }
787     break;
788     case IdSerial:
789     break;
790     }
791     cv->RRQ = TRUE;
792     CommReceive(cv);
793     }
794    
795     void CommReceive(PComVar cv)
796     {
797     DWORD C;
798     DWORD DErr;
799    
800     if (! cv->Ready || ! cv->RRQ ||
801     (cv->InBuffCount>=InBuffSize)) {
802     return;
803     }
804    
805     /* Compact buffer */
806     if ((cv->InBuffCount>0) && (cv->InPtr>0)) {
807     memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount);
808     cv->InPtr = 0;
809     }
810    
811     if (cv->InBuffCount<InBuffSize) {
812     switch (cv->PortType) {
813     case IdTCPIP:
814     C = Precv(cv->s, &(cv->InBuff[cv->InBuffCount]),
815     InBuffSize-cv->InBuffCount, 0);
816     if (C == SOCKET_ERROR) {
817     C = 0;
818     PWSAGetLastError();
819     }
820     cv->InBuffCount = cv->InBuffCount + C;
821     break;
822     case IdSerial:
823     do {
824     ClearCommError(cv->ComID,&DErr,NULL);
825     if (! PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),
826     InBuffSize-cv->InBuffCount,&C,&rol)) {
827     if (GetLastError() == ERROR_IO_PENDING) {
828     if (WaitForSingleObject(rol.hEvent, 1000) != WAIT_OBJECT_0) {
829     C = 0;
830     }
831     else {
832     GetOverlappedResult(cv->ComID,&rol,&C,FALSE);
833     }
834     }
835     else {
836     C = 0;
837     }
838     }
839     cv->InBuffCount = cv->InBuffCount + C;
840     } while ((C!=0) && (cv->InBuffCount<InBuffSize));
841     ClearCommError(cv->ComID,&DErr,NULL);
842     break;
843     case IdFile:
844     if (PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),
845     InBuffSize-cv->InBuffCount,&C,NULL)) {
846     if (C == 0) {
847     DErr = ERROR_HANDLE_EOF;
848     }
849     else {
850     cv->InBuffCount = cv->InBuffCount + C;
851     }
852     }
853     else {
854     DErr = GetLastError();
855     }
856     break;
857     }
858     }
859    
860     if (cv->InBuffCount==0) {
861     switch (cv->PortType) {
862     case IdTCPIP:
863     if (! TCPIPClosed) {
864     PWSAAsyncSelect(cv->s,cv->HWin, WM_USER_COMMNOTIFY,
865     FD_READ | FD_OOB | FD_CLOSE);
866     }
867     break;
868     case IdSerial:
869     cv->RRQ = FALSE;
870     SetEvent(ReadEnd);
871     return;
872     case IdFile:
873     if (DErr != ERROR_IO_PENDING) {
874     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
875     cv->RRQ = FALSE;
876     }
877     else {
878     cv->RRQ = TRUE;
879     }
880     return;
881     }
882     cv->RRQ = FALSE;
883     }
884     }
885    
886     void CommSend(PComVar cv)
887     {
888     int delay;
889     COMSTAT Stat;
890     BYTE LineEnd;
891     int C, D, Max;
892     DWORD DErr;
893    
894     if ((! cv->Open) || (! cv->Ready)) {
895     cv->OutBuffCount = 0;
896     return;
897     }
898    
899     if ((cv->OutBuffCount == 0) || (! cv->CanSend)) {
900     return;
901     }
902    
903     /* Max num of bytes to be written */
904     switch (cv->PortType) {
905     case IdTCPIP:
906     if (TCPIPClosed) {
907     cv->OutBuffCount = 0;
908     }
909     Max = cv->OutBuffCount;
910     break;
911     case IdSerial:
912     ClearCommError(cv->ComID,&DErr,&Stat);
913     Max = OutBuffSize - Stat.cbOutQue;
914     break;
915     case IdFile:
916     Max = cv->OutBuffCount;
917     break;
918     }
919    
920     if ( Max<=0 ) {
921     return;
922     }
923     if ( Max > cv->OutBuffCount ) {
924     Max = cv->OutBuffCount;
925     }
926    
927     if (cv->PortType == IdTCPIP && cv->TelFlag) {
928     cv->LastSendTime = time(NULL);
929     }
930    
931     C = Max;
932     delay = 0;
933    
934     if ( cv->DelayFlag && (cv->PortType==IdSerial) ) {
935     if ( cv->DelayPerLine > 0 ) {
936     if ( cv->CRSend==IdCR ) {
937     LineEnd = 0x0d;
938     }
939     else {
940     LineEnd = 0x0a;
941     }
942     C = 1;
943     if ( cv->DelayPerChar==0 ) {
944     while ((C<Max) && (cv->OutBuff[cv->OutPtr+C-1]!=LineEnd)) {
945     C++;
946     }
947     }
948     if ( cv->OutBuff[cv->OutPtr+C-1]==LineEnd ) {
949     delay = cv->DelayPerLine;
950     }
951     else {
952     delay = cv->DelayPerChar;
953     }
954     }
955     else if ( cv->DelayPerChar > 0 ) {
956     C = 1;
957     delay = cv->DelayPerChar;
958     }
959     }
960    
961     /* Write to comm driver/Winsock */
962     switch (cv->PortType) {
963     case IdTCPIP:
964     D = Psend(cv->s, &(cv->OutBuff[cv->OutPtr]), C, 0);
965     if ( D==SOCKET_ERROR ) { /* if error occurs */
966     PWSAGetLastError(); /* Clear error */
967     D = 0;
968     }
969     break;
970    
971     case IdSerial:
972     if (! PWriteFile(cv->ComID,&(cv->OutBuff[cv->OutPtr]),C,(LPDWORD)&D,&wol)) {
973     if (GetLastError() == ERROR_IO_PENDING) {
974     if (WaitForSingleObject(wol.hEvent,1000) != WAIT_OBJECT_0) {
975     D = C; /* Time out, ignore data */
976     }
977     else {
978     GetOverlappedResult(cv->ComID,&wol,(LPDWORD)&D,FALSE);
979     }
980     }
981     else { /* I/O error */
982     D = C; /* ignore error */
983     }
984     }
985     ClearCommError(cv->ComID,&DErr,&Stat);
986     break;
987    
988     case IdFile:
989     if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) {
990     if (! GetLastError() == ERROR_IO_PENDING) {
991     D = C; /* ignore data */
992     }
993     }
994     break;
995     }
996    
997     cv->OutBuffCount = cv->OutBuffCount - D;
998     if ( cv->OutBuffCount==0 ) {
999     cv->OutPtr = 0;
1000     }
1001     else {
1002     cv->OutPtr = cv->OutPtr + D;
1003     }
1004    
1005     if ( (C==D) && (delay>0) ) {
1006     cv->CanSend = FALSE;
1007     SetTimer(cv->HWin, IdDelayTimer, delay, NULL);
1008     }
1009     }
1010    
1011     void CommSendBreak(PComVar cv)
1012     /* for only serial ports */
1013     {
1014     MSG DummyMsg;
1015    
1016     if ( ! cv->Ready ) {
1017     return;
1018     }
1019    
1020     switch (cv->PortType) {
1021     case IdSerial:
1022     /* Set com port into a break state */
1023     SetCommBreak(cv->ComID);
1024    
1025     /* pause for 1 sec */
1026     if (SetTimer(cv->HWin, IdBreakTimer, 1000, NULL) != 0) {
1027     GetMessage(&DummyMsg,cv->HWin,WM_TIMER,WM_TIMER);
1028     }
1029    
1030     /* Set com port into the nonbreak state */
1031     ClearCommBreak(cv->ComID);
1032     break;
1033     }
1034     }
1035    
1036     void CommLock(PTTSet ts, PComVar cv, BOOL Lock)
1037     {
1038     BYTE b;
1039     DWORD Func;
1040    
1041     if (! cv->Ready) {
1042     return;
1043     }
1044     if ((cv->PortType==IdTCPIP) ||
1045     (cv->PortType==IdSerial) &&
1046     (ts->Flow!=IdFlowHard)) {
1047     if (Lock) {
1048     b = XOFF;
1049     }
1050     else {
1051     b = XON;
1052     }
1053     CommBinaryOut(cv,&b,1);
1054     }
1055     else if ((cv->PortType==IdSerial) &&
1056     (ts->Flow==IdFlowHard)) {
1057     if (Lock) {
1058     Func = CLRRTS;
1059     }
1060     else {
1061     Func = SETRTS;
1062     }
1063     EscapeCommFunction(cv->ComID,Func);
1064     }
1065     }
1066    
1067     BOOL PrnOpen(PCHAR DevName)
1068     {
1069     char Temp[MAXPATHLEN];
1070     DCB dcb;
1071     DWORD DErr;
1072     COMMTIMEOUTS ctmo;
1073    
1074     strncpy_s(Temp, sizeof(Temp),DevName, _TRUNCATE);
1075     Temp[4] = 0; // COMn or LPTn
1076     LPTFlag = (Temp[0]=='L') ||
1077     (Temp[0]=='l');
1078     PrnID = CreateFile(Temp,GENERIC_WRITE,
1079     0,NULL,OPEN_EXISTING,
1080     0,NULL);
1081     if (PrnID == INVALID_HANDLE_VALUE) {
1082     return FALSE;
1083     }
1084    
1085     if (GetCommState(PrnID,&dcb)) {
1086     BuildCommDCB(DevName,&dcb);
1087     SetCommState(PrnID,&dcb);
1088     }
1089     ClearCommError(PrnID,&DErr,NULL);
1090     if (! LPTFlag) {
1091     SetupComm(PrnID,0,CommOutQueSize);
1092     }
1093     /* flush output buffer */
1094     PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR);
1095     memset(&ctmo,0,sizeof(ctmo));
1096     ctmo.WriteTotalTimeoutConstant = 1000;
1097     SetCommTimeouts(PrnID,&ctmo);
1098     if (! LPTFlag) {
1099     EscapeCommFunction(PrnID,SETDTR);
1100     }
1101     return TRUE;
1102     }
1103    
1104     int PrnWrite(PCHAR b, int c)
1105     {
1106     int d;
1107     DWORD DErr;
1108     COMSTAT Stat;
1109    
1110     if (PrnID == INVALID_HANDLE_VALUE ) {
1111     return c;
1112     }
1113    
1114     ClearCommError(PrnID,&DErr,&Stat);
1115     if (! LPTFlag &&
1116     (OutBuffSize - (int)Stat.cbOutQue < c)) {
1117     c = OutBuffSize - Stat.cbOutQue;
1118     }
1119     if (c<=0) {
1120     return 0;
1121     }
1122     if (! WriteFile(PrnID,b,c,(LPDWORD)&d,NULL)) {
1123     d = 0;
1124     }
1125     ClearCommError(PrnID,&DErr,NULL);
1126     return d;
1127     }
1128    
1129     void PrnCancel()
1130     {
1131     PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR);
1132     PrnClose();
1133     }
1134    
1135     void PrnClose()
1136     {
1137     if (PrnID != INVALID_HANDLE_VALUE) {
1138     if (!LPTFlag) {
1139     EscapeCommFunction(PrnID,CLRDTR);
1140     }
1141     CloseHandle(PrnID);
1142     }
1143     PrnID = INVALID_HANDLE_VALUE;
1144     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26