Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ttcomtester/teraterm/teraterm/commlib.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3393 - (show 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 /* Tera Term
2 Copyright(C) 1994-1998 T. Teranishi
3 All rights reserved. */
4 /* IPv6 modification is Copyright (C) 2000, 2001 Jun-ya KATO <kato@win6.jp> */
5
6 /* TERATERM.EXE, Communication routines */
7 #include "teraterm.h"
8 #include "tttypes.h"
9 #include "tt_res.h"
10 #include <process.h>
11
12 #include "ttcommon.h"
13 #include "ttwsk.h"
14 #include "ttlib.h"
15 #include "ttfileio.h"
16 #include "ttplug.h" /* TTPLUG */
17
18 #include "commlib.h"
19 #ifndef NO_INET6
20 #include <winsock2.h>
21 #include <ws2tcpip.h>
22 #include <stdio.h> /* for _snprintf() */
23 #include "WSAAsyncGetAddrInfo.h"
24 #endif /* NO_INET6 */
25 #include <time.h>
26
27 static SOCKET OpenSocket(PComVar);
28 static void AsyncConnect(PComVar);
29 static int CloseSocket(SOCKET);
30
31 /* create socket */
32 static SOCKET OpenSocket(PComVar cv)
33 {
34 cv->s = cv->res->ai_family;
35 cv->s = Psocket(cv->res->ai_family, cv->res->ai_socktype, cv->res->ai_protocol);
36 return cv->s;
37 }
38
39 /* connect with asynchronous mode */
40 static void AsyncConnect(PComVar cv)
41 {
42 int Err;
43 BOOL BBuf;
44 BBuf = TRUE;
45 /* set synchronous mode */
46 PWSAAsyncSelect(cv->s,cv->HWin,0,0);
47 Psetsockopt(cv->s,(int)SOL_SOCKET,SO_OOBINLINE,(char FAR *)&BBuf,sizeof(BBuf));
48 /* set asynchronous mode */
49 PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMOPEN, FD_CONNECT);
50
51 // �z�X�g���������������������������A�����I���\�P�b�g���N���[�Y�����A
52 // �����������L�����Z���������B�l��0�������������������B
53 // (2007.1.11 yutaka)
54 if (*cv->ConnetingTimeout > 0) {
55 SetTimer(cv->HWin, IdCancelConnectTimer, *cv->ConnetingTimeout * 1000, NULL);
56 }
57
58 /* WM_USER_COMMOPEN occurs, CommOpen is called, then CommStart is called */
59 Err = Pconnect(cv->s, cv->res->ai_addr, cv->res->ai_addrlen);
60 if (Err != 0) {
61 Err = PWSAGetLastError();
62 if (Err == WSAEWOULDBLOCK) {
63 /* Do nothing */
64 } else if (Err!=0 ) {
65 PostMessage(cv->HWin, WM_USER_COMMOPEN,0,
66 MAKELONG(FD_CONNECT,Err));
67 }
68 }
69 }
70
71 /* close socket */
72 static int CloseSocket(SOCKET s)
73 {
74 return Pclosesocket(s);
75 }
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 cv->Open = FALSE;
106 cv->Ready = FALSE;
107
108 // log-buffer variables
109 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 /* message flag */
125 cv->NoMsg = 0;
126 }
127
128 /* reset a serial port which is already open */
129 void CommResetSerial(PTTSet ts, PComVar cv, BOOL ClearBuff)
130 {
131 DCB dcb;
132 DWORD DErr;
133 COMMTIMEOUTS ctmo;
134
135 if (! cv->Open ||
136 (cv->PortType != IdSerial)) {
137 return;
138 }
139
140 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
148 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
157 cv->DelayPerChar = ts->DelayPerChar;
158 cv->DelayPerLine = ts->DelayPerLine;
159
160 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
178 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
195 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
212 SetCommState(cv->ComID, &dcb);
213
214 /* enable receive request */
215 SetCommMask(cv->ComID,0);
216 SetCommMask(cv->ComID,EV_RXCHAR);
217 }
218
219 void CommOpen(HWND HW, PTTSet ts, PComVar cv)
220 {
221 #ifdef NO_INET6
222 int Err;
223 #endif /* NO_INET6 */
224 char ErrMsg[21];
225 char P[50];
226
227 MSG Msg;
228 #ifndef NO_INET6
229 ADDRINFO hints;
230 char pname[NI_MAXSERV];
231 #else
232 char HEntBuff[MAXGETHOSTSTRUCT];
233 u_long addr;
234 SOCKADDR_IN saddr;
235 #endif /* NO_INET6 */
236
237 BOOL InvalidHost;
238 #ifdef NO_INET6
239 BOOL BBuf;
240 #endif /* NO_INET6 */
241
242 char uimsg[MAX_UIMSG];
243
244 /* 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 #ifndef NO_INET6
256 cv->RetryWithOtherProtocol = TRUE;
257 #endif /* NO_INET6 */
258 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
293 if ((ts->PortType!=IdSerial) && (strlen(ts->HostName)==0))
294 {
295 PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
296 return;
297 }
298
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 #ifndef NO_INET6
314 /* 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
321 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
359 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 #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 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
488 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
502 /* notify to VT window that Comm Port is open */
503 PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);
504 InvalidHost = FALSE;
505
506 SetCOMFlag(ts->ComPort);
507 }
508 break; /* end of "case IdSerial:" */
509
510 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
530 #ifndef NO_INET6
531 BreakSC:
532 #endif /* NO_INET6 */
533 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 }
544
545 void CommThread(void *arg)
546 {
547 DWORD Evt;
548 PComVar cv = (PComVar)arg;
549 DWORD DErr;
550 HANDLE REnd;
551 char Temp[20];
552
553 _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 }
573
574 void CommStart(PComVar cv, LONG lParam, PTTSet ts)
575 {
576 char ErrMsg[31];
577 char Temp[20];
578 char uimsg[MAX_UIMSG];
579
580 if (! cv->Open ) {
581 return;
582 }
583 if ( cv->Ready ) {
584 return;
585 }
586
587 // �L�����Z���^�C�}�����������������B�������A�������_�� WM_TIMER �����������������\���������B
588 if (*cv->ConnetingTimeout > 0) {
589 KillTimer(cv->HWin, IdCancelConnectTimer);
590 }
591
592 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 #ifndef NO_INET6
614 /* 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 #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 }
648
649 #ifndef NO_INET6
650 /* here is connection established */
651 cv->RetryWithOtherProtocol = FALSE;
652 #endif /* NO_INET6 */
653 PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_READ | FD_OOB | FD_CLOSE);
654 TCPIPClosed = FALSE;
655 break;
656
657 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
667 /* 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
675 case IdFile:
676 cv->RRQ = TRUE;
677 break;
678 }
679 cv->Ready = TRUE;
680 }
681
682 BOOL CommCanClose(PComVar cv)
683 { // check if data remains in buffer
684 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 }
701
702 void CommClose(PComVar cv)
703 {
704 if ( ! cv->Open ) {
705 return;
706 }
707 cv->Open = FALSE;
708
709 /* 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
717 /* close port & release resources */
718 switch (cv->PortType) {
719 case IdTCPIP:
720 if (HAsync!=0) {
721 PWSACancelAsyncRequest(HAsync);
722 }
723 HAsync = 0;
724 #ifndef NO_INET6
725 freeaddrinfo(cv->res0);
726 #endif /* NO_INET6 */
727 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 }
758
759 void CommProcRRQ(PComVar cv)
760 {
761 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 }
777
778 void CommReceive(PComVar cv)
779 {
780 DWORD C;
781 DWORD DErr;
782
783 if (! cv->Ready || ! cv->RRQ ||
784 (cv->InBuffCount>=InBuffSize)) {
785 return;
786 }
787
788 /* 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
794 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 }
842
843 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 }
867 }
868
869 void CommSend(PComVar cv)
870 {
871 int delay;
872 COMSTAT Stat;
873 BYTE LineEnd;
874 int C, D, Max;
875 DWORD DErr;
876
877 if ((! cv->Open) || (! cv->Ready)) {
878 cv->OutBuffCount = 0;
879 return;
880 }
881
882 if ((cv->OutBuffCount == 0) || (! cv->CanSend)) {
883 return;
884 }
885
886 /* 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
903 if ( Max<=0 ) {
904 return;
905 }
906 if ( Max > cv->OutBuffCount ) {
907 Max = cv->OutBuffCount;
908 }
909
910 if (cv->PortType == IdTCPIP && cv->TelFlag) {
911 cv->LastSendTime = time(NULL);
912 }
913
914 C = Max;
915 delay = 0;
916
917 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
944 /* 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
954 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 }
979
980 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
988 if ( (C==D) && (delay>0) ) {
989 cv->CanSend = FALSE;
990 SetTimer(cv->HWin, IdDelayTimer, delay, NULL);
991 }
992 }
993
994 void CommSendBreak(PComVar cv)
995 /* for only serial ports */
996 {
997 MSG DummyMsg;
998
999 if ( ! cv->Ready ) {
1000 return;
1001 }
1002
1003 switch (cv->PortType) {
1004 case IdSerial:
1005 /* Set com port into a break state */
1006 SetCommBreak(cv->ComID);
1007
1008 /* pause for 1 sec */
1009 if (SetTimer(cv->HWin, IdBreakTimer, 1000, NULL) != 0) {
1010 GetMessage(&DummyMsg,cv->HWin,WM_TIMER,WM_TIMER);
1011 }
1012
1013 /* Set com port into the nonbreak state */
1014 ClearCommBreak(cv->ComID);
1015 break;
1016 }
1017 }
1018
1019 void CommLock(PTTSet ts, PComVar cv, BOOL Lock)
1020 {
1021 BYTE b;
1022 DWORD Func;
1023
1024 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 }
1049
1050 int GetCommSerialBaudRate(int id)
1051 {
1052 char *ch;
1053 int val;
1054
1055 // id-1�����X�g��index�������B
1056 ch = BaudList[id - 1];
1057 val = atoi(ch);
1058 return (val);
1059 }
1060
1061 BOOL PrnOpen(PCHAR DevName)
1062 {
1063 char Temp[MAXPATHLEN];
1064 DCB dcb;
1065 DWORD DErr;
1066 COMMTIMEOUTS ctmo;
1067
1068 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
1079 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 }
1097
1098 int PrnWrite(PCHAR b, int c)
1099 {
1100 int d;
1101 DWORD DErr;
1102 COMSTAT Stat;
1103
1104 if (PrnID == INVALID_HANDLE_VALUE ) {
1105 return c;
1106 }
1107
1108 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 }
1122
1123 void PrnCancel()
1124 {
1125 PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR);
1126 PrnClose();
1127 }
1128
1129 void PrnClose()
1130 {
1131 if (PrnID != INVALID_HANDLE_VALUE) {
1132 if (!LPTFlag) {
1133 EscapeCommFunction(PrnID,CLRDTR);
1134 }
1135 CloseHandle(PrnID);
1136 }
1137 PrnID = INVALID_HANDLE_VALUE;
1138 }

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