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 3494 - (hide annotations) (download) (as text)
Mon Jun 15 18:37:05 2009 UTC (14 years, 9 months ago) by doda
Original Path: trunk/teraterm/teraterm/commlib.c
File MIME type: text/x-csrc
File size: 28713 byte(s)
Line at a timeモードに仮対応

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

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