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

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