Develop and Download Open Source Software

Browse Subversion Repository

Diff of /trunk/teraterm/teraterm/commlib.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.3221  
changed lines
  Added in v.3227

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