Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/commlib.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3268 - (hide annotations) (download) (as text)
Wed Apr 1 10:55:13 2009 UTC (14 years, 11 months ago) by yutakapon
File MIME type: text/x-csrc
File size: 28583 byte(s)
ボーレートの定義が、あちこちに重複していたため、Tttypes.h ヘッダに集約させた。

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

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