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 3501 - (hide annotations) (download) (as text)
Tue Jun 16 07:43:31 2009 UTC (14 years, 8 months ago) by doda
Original Path: trunk/teraterm/teraterm/commlib.c
File MIME type: text/x-csrc
File size: 28750 byte(s)
Line at a timeモードを無効に設定できるようにした。
  EnableLineMode=off

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

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