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 2476 - (hide annotations) (download) (as text)
Mon Apr 14 17:35:50 2008 UTC (16 years ago) by maya
Original Path: teraterm/trunk/teraterm/commlib.c
File MIME type: text/x-csrc
File size: 27945 byte(s)
ファイル移動に伴う修正

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

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