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

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