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

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