Develop and Download Open Source Software

Browse Subversion Repository

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

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

revision 3268 by yutakapon, Wed Apr 1 10:55:13 2009 UTC revision 3393 by maya, Tue May 12 14:26:30 2009 UTC
# Line 31  static int CloseSocket(SOCKET); Line 31  static int CloseSocket(SOCKET);
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      {                          /* Do nothing */
64        /* Do nothing */                  } else if (Err!=0 ) {
65      } else if (Err!=0 ) {                          PostMessage(cv->HWin, WM_USER_COMMOPEN,0,
66        PostMessage(cv->HWin, WM_USER_COMMOPEN,0,                                      MAKELONG(FD_CONNECT,Err));
67                    MAKELONG(FD_CONNECT,Err));                  }
68      }          }
   }  
69  }  }
70    
71  /* close socket */  /* close socket */
72  static int CloseSocket(SOCKET s)  static int CloseSocket(SOCKET s)
73  {  {
74    return Pclosesocket(s);          return Pclosesocket(s);
75  }  }
76    
77  #define CommInQueSize 8192  #define CommInQueSize 8192
# Line 103  static BOOL LPTFlag; Line 102  static BOOL LPTFlag;
102  // by the initialization procedure of Tera Term.  // by the initialization procedure of Tera Term.
103  void CommInit(PComVar cv)  void CommInit(PComVar cv)
104  {  {
105    cv->Open = FALSE;          cv->Open = FALSE;
106    cv->Ready = FALSE;          cv->Ready = FALSE;
107    
108  // log-buffer variables  // log-buffer variables
109    cv->HLogBuf = 0;          cv->HLogBuf = 0;
110    cv->HBinBuf = 0;          cv->HBinBuf = 0;
111    cv->LogBuf = NULL;          cv->LogBuf = NULL;
112    cv->BinBuf = NULL;          cv->BinBuf = NULL;
113    cv->LogPtr = 0;          cv->LogPtr = 0;
114    cv->LStart = 0;          cv->LStart = 0;
115    cv->LCount = 0;          cv->LCount = 0;
116    cv->BinPtr = 0;          cv->BinPtr = 0;
117    cv->BStart = 0;          cv->BStart = 0;
118    cv->BCount = 0;          cv->BCount = 0;
119    cv->DStart = 0;          cv->DStart = 0;
120    cv->DCount = 0;          cv->DCount = 0;
121    cv->BinSkip = 0;          cv->BinSkip = 0;
122    cv->FilePause = 0;          cv->FilePause = 0;
123    cv->ProtoFlag = FALSE;          cv->ProtoFlag = FALSE;
124  /* message flag */  /* message flag */
125    cv->NoMsg = 0;          cv->NoMsg = 0;
126  }  }
127    
128  /* reset a serial port which is already open */  /* reset a serial port which is already open */
129  void CommResetSerial(PTTSet ts, PComVar cv, BOOL ClearBuff)  void CommResetSerial(PTTSet ts, PComVar cv, BOOL ClearBuff)
130  {  {
131    DCB dcb;          DCB dcb;
132    DWORD DErr;          DWORD DErr;
133    COMMTIMEOUTS ctmo;          COMMTIMEOUTS ctmo;
134    
135    if (! cv->Open ||          if (! cv->Open ||
136        (cv->PortType != IdSerial)) return;                  (cv->PortType != IdSerial)) {
137                            return;
138    ClearCommError(cv->ComID,&DErr,NULL);          }
   SetupComm(cv->ComID,CommInQueSize,CommOutQueSize);  
   /* flush input and output buffers */  
   if (ClearBuff)  
     PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT |  
       PURGE_TXCLEAR | PURGE_RXCLEAR);  
   
   memset(&ctmo,0,sizeof(ctmo));  
   ctmo.ReadIntervalTimeout = MAXDWORD;  
   ctmo.WriteTotalTimeoutConstant = 500;  
   SetCommTimeouts(cv->ComID,&ctmo);  
   cv->InBuffCount = 0;  
   cv->InPtr = 0;  
   cv->OutBuffCount = 0;  
   cv->OutPtr = 0;  
   
   cv->DelayPerChar = ts->DelayPerChar;  
   cv->DelayPerLine = ts->DelayPerLine;  
   
   memset(&dcb,0,sizeof(DCB));  
   dcb.DCBlength = sizeof(DCB);  
   dcb.BaudRate = GetCommSerialBaudRate(ts->Baud);  
   dcb.fBinary = TRUE;  
   switch (ts->Parity) {  
     case IdParityEven:  
       dcb.fParity = TRUE;  
       dcb.Parity = EVENPARITY;  
       break;  
     case IdParityOdd:  
       dcb.fParity = TRUE;  
       dcb.Parity = ODDPARITY;  
       break;  
     case IdParityNone:  
       dcb.Parity = NOPARITY;  
       break;  
   }  
139    
140    dcb.fDtrControl = DTR_CONTROL_ENABLE;          ClearCommError(cv->ComID,&DErr,NULL);
141    dcb.fRtsControl = RTS_CONTROL_ENABLE;          SetupComm(cv->ComID,CommInQueSize,CommOutQueSize);
142    switch (ts->Flow) {          /* flush input and output buffers */
143      case IdFlowX:          if (ClearBuff) {
144        dcb.fOutX = TRUE;                  PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT |
145        dcb.fInX = TRUE;                                       PURGE_TXCLEAR | PURGE_RXCLEAR);
146        dcb.XonLim = CommXonLim;          }
147        dcb.XoffLim = CommXoffLim;  
148        dcb.XonChar = XON;          memset(&ctmo,0,sizeof(ctmo));
149        dcb.XoffChar = XOFF;          ctmo.ReadIntervalTimeout = MAXDWORD;
150        break;          ctmo.WriteTotalTimeoutConstant = 500;
151      case IdFlowHard:          SetCommTimeouts(cv->ComID,&ctmo);
152        dcb.fOutxCtsFlow = TRUE;          cv->InBuffCount = 0;
153        dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;          cv->InPtr = 0;
154        break;          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    switch (ts->DataBit) {          /* enable receive request */
215      case IdDataBit7: dcb.ByteSize = 7; break;          SetCommMask(cv->ComID,0);
216      case IdDataBit8: dcb.ByteSize = 8; break;          SetCommMask(cv->ComID,EV_RXCHAR);
   }  
   switch (ts->StopBit) {  
     case IdStopBit1: dcb.StopBits = ONESTOPBIT; break;  
     case IdStopBit2: dcb.StopBits = TWOSTOPBITS; break;  
   }  
   
   SetCommState(cv->ComID, &dcb);  
   
   /* enable receive request */  
   SetCommMask(cv->ComID,0);  
   SetCommMask(cv->ComID,EV_RXCHAR);  
217  }  }
218    
219  void CommOpen(HWND HW, PTTSet ts, PComVar cv)  void CommOpen(HWND HW, PTTSet ts, PComVar cv)
220  {  {
221  #ifdef NO_INET6  #ifdef NO_INET6
222    int Err;          int Err;
223  #endif /* NO_INET6 */  #endif /* NO_INET6 */
224    char ErrMsg[21];          char ErrMsg[21];
225    char P[50];          char P[50];
226    
227    MSG Msg;          MSG Msg;
228  #ifndef NO_INET6  #ifndef NO_INET6
229    ADDRINFO hints;          ADDRINFO hints;
230    char pname[NI_MAXSERV];          char pname[NI_MAXSERV];
231  #else  #else
232    char HEntBuff[MAXGETHOSTSTRUCT];          char HEntBuff[MAXGETHOSTSTRUCT];
233    u_long addr;          u_long addr;
234    SOCKADDR_IN saddr;          SOCKADDR_IN saddr;
235  #endif /* NO_INET6 */  #endif /* NO_INET6 */
236    
237    BOOL InvalidHost;          BOOL InvalidHost;
238  #ifdef NO_INET6  #ifdef NO_INET6
239    BOOL BBuf;          BOOL BBuf;
240  #endif /* NO_INET6 */  #endif /* NO_INET6 */
241    
242    char uimsg[MAX_UIMSG];          char uimsg[MAX_UIMSG];
243    
244    /* initialize ComVar */          /* initialize ComVar */
245    cv->InBuffCount = 0;          cv->InBuffCount = 0;
246    cv->InPtr = 0;          cv->InPtr = 0;
247    cv->OutBuffCount = 0;          cv->OutBuffCount = 0;
248    cv->OutPtr = 0;          cv->OutPtr = 0;
249    cv->HWin = HW;          cv->HWin = HW;
250    cv->Ready = FALSE;          cv->Ready = FALSE;
251    cv->Open = FALSE;          cv->Open = FALSE;
252    cv->PortType = ts->PortType;          cv->PortType = ts->PortType;
253    cv->ComPort = 0;          cv->ComPort = 0;
254    cv->RetryCount = 0;          cv->RetryCount = 0;
255  #ifndef NO_INET6  #ifndef NO_INET6
256    cv->RetryWithOtherProtocol = TRUE;          cv->RetryWithOtherProtocol = TRUE;
257  #endif /* NO_INET6 */  #endif /* NO_INET6 */
258    cv->s = INVALID_SOCKET;          cv->s = INVALID_SOCKET;
259    cv->ComID = INVALID_HANDLE_VALUE;          cv->ComID = INVALID_HANDLE_VALUE;
260    cv->CanSend = TRUE;          cv->CanSend = TRUE;
261    cv->RRQ = FALSE;          cv->RRQ = FALSE;
262    cv->SendKanjiFlag = FALSE;          cv->SendKanjiFlag = FALSE;
263    cv->SendCode = IdASCII;          cv->SendCode = IdASCII;
264    cv->EchoKanjiFlag = FALSE;          cv->EchoKanjiFlag = FALSE;
265    cv->EchoCode = IdASCII;          cv->EchoCode = IdASCII;
266    cv->Language = ts->Language;          cv->Language = ts->Language;
267    cv->CRSend = ts->CRSend;          cv->CRSend = ts->CRSend;
268    cv->KanjiCodeEcho = ts->KanjiCode;          cv->KanjiCodeEcho = ts->KanjiCode;
269    cv->JIS7KatakanaEcho = ts->JIS7Katakana;          cv->JIS7KatakanaEcho = ts->JIS7Katakana;
270    cv->KanjiCodeSend = ts->KanjiCodeSend;          cv->KanjiCodeSend = ts->KanjiCodeSend;
271    cv->JIS7KatakanaSend = ts->JIS7KatakanaSend;          cv->JIS7KatakanaSend = ts->JIS7KatakanaSend;
272    cv->KanjiIn = ts->KanjiIn;          cv->KanjiIn = ts->KanjiIn;
273    cv->KanjiOut = ts->KanjiOut;          cv->KanjiOut = ts->KanjiOut;
274    cv->RussHost = ts->RussHost;          cv->RussHost = ts->RussHost;
275    cv->RussClient = ts->RussClient;          cv->RussClient = ts->RussClient;
276    cv->DelayFlag = TRUE;          cv->DelayFlag = TRUE;
277    cv->DelayPerChar = ts->DelayPerChar;          cv->DelayPerChar = ts->DelayPerChar;
278    cv->DelayPerLine = ts->DelayPerLine;          cv->DelayPerLine = ts->DelayPerLine;
279    cv->TelBinRecv = FALSE;          cv->TelBinRecv = FALSE;
280    cv->TelBinSend = FALSE;          cv->TelBinSend = FALSE;
281    cv->TelFlag = FALSE;          cv->TelFlag = FALSE;
282    cv->TelMode = FALSE;          cv->TelMode = FALSE;
283    cv->IACFlag = FALSE;          cv->IACFlag = FALSE;
284    cv->TelCRFlag = FALSE;          cv->TelCRFlag = FALSE;
285    cv->TelCRSend = FALSE;          cv->TelCRSend = FALSE;
286    cv->TelCRSendEcho = FALSE;          cv->TelCRSendEcho = FALSE;
287    cv->TelAutoDetect = ts->TelAutoDetect; /* TTPLUG */          cv->TelAutoDetect = ts->TelAutoDetect; /* TTPLUG */
288    cv->Locale = ts->Locale;          cv->Locale = ts->Locale;
289    cv->CodePage = &ts->CodePage;          cv->CodePage = &ts->CodePage;
290    cv->ConnetingTimeout = &ts->ConnectingTimeout;          cv->ConnetingTimeout = &ts->ConnectingTimeout;
291    cv->LastSendTime = time(NULL);          cv->LastSendTime = time(NULL);
292    
293    if ((ts->PortType!=IdSerial) && (strlen(ts->HostName)==0))          if ((ts->PortType!=IdSerial) && (strlen(ts->HostName)==0))
   {  
     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);  
     return;  
   }  
   
   switch (ts->PortType) {  
     case IdTCPIP:  
       cv->TelFlag = (ts->Telnet > 0);  
       if (! LoadWinsock())  
       {  
         if (cv->NoMsg==0)  
294          {          {
295            get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                  PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
           get_lang_msg("MSG_WINSOCK_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot use winsock", ts->UILanguageFile);  
           MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);  
         }  
         InvalidHost = TRUE;  
       }  
       else {  
         TTXOpenTCP(); /* TTPLUG */  
         cv->Open = TRUE;  
 #ifndef NO_INET6  
         /* resolving address */  
         memset(&hints, 0, sizeof(hints));  
         hints.ai_family = ts->ProtocolFamily;  
         hints.ai_socktype = SOCK_STREAM;  
         hints.ai_protocol = IPPROTO_TCP;  
         _snprintf_s(pname, sizeof(pname), _TRUNCATE, "%d", ts->TCPPort);  
   
         HAsync = WSAAsyncGetAddrInfo(HW, WM_USER_GETHOST,  
                                      ts->HostName, pname, &hints, &cv->res0);  
         if (HAsync == 0)  
           InvalidHost = TRUE;  
         else {  
             cv->ComPort = 1; // set "getting host" flag  
                              //  (see CVTWindow::OnSysCommand())  
             do {  
               if (GetMessage(&Msg,0,0,0))  
               {  
                 if ((Msg.hwnd==HW) &&  
                     ((Msg.message == WM_SYSCOMMAND) &&  
                      ((Msg.wParam & 0xfff0) == SC_CLOSE) ||  
                      (Msg.message == WM_COMMAND) &&  
                      (LOWORD(Msg.wParam) == ID_FILE_EXIT) ||  
                      (Msg.message == WM_CLOSE)))  
                 { /* Exit when the user closes Tera Term */  
                   PWSACancelAsyncRequest(HAsync);  
                   CloseHandle(HAsync);  
                   HAsync = 0;  
                   cv->ComPort = 0; // clear "getting host" flag  
                   PostMessage(HW,Msg.message,Msg.wParam,Msg.lParam);  
                   return;  
                 }  
                 if (Msg.message != WM_USER_GETHOST)  
                 { /* Prosess messages */  
                   TranslateMessage(&Msg);  
                   DispatchMessage(&Msg);  
                 }  
               }  
               else {  
296                  return;                  return;
               }  
             } while (Msg.message!=WM_USER_GETHOST);  
             cv->ComPort = 0; // clear "getting host" flag  
         CloseHandle(HAsync);  
             HAsync = 0;  
             InvalidHost = WSAGETASYNCERROR(Msg.lParam) != 0;  
297          }          }
       } /* if (!LoadWinsock()) */  
298    
299        if (InvalidHost)          switch (ts->PortType) {
300        {                  case IdTCPIP:
301          if (cv->NoMsg==0)                          cv->TelFlag = (ts->Telnet > 0);
302          {                          if (! LoadWinsock()) {
303            get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                  if (cv->NoMsg==0) {
304            get_lang_msg("MSG_INVALID_HOST_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Invalid host", ts->UILanguageFile);                                          get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
305            MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                          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          goto BreakSC;                                  }
308        }                                  InvalidHost = TRUE;
309        for (cv->res = cv->res0; cv->res; cv->res = cv->res->ai_next) {                          }
310          cv->s =  OpenSocket(cv);                          else {
311          if (cv->s == INVALID_SOCKET) {                                  TTXOpenTCP(); /* TTPLUG */
312            CloseSocket(cv->s);                                  cv->Open = TRUE;
313            continue;  #ifndef NO_INET6
314          }                                  /* resolving address */
315          /* start asynchronous connect */                                  memset(&hints, 0, sizeof(hints));
316          AsyncConnect(cv);                                  hints.ai_family = ts->ProtocolFamily;
317          break; /* break for-loop immediately */                                  hints.ai_socktype = SOCK_STREAM;
318        }                                  hints.ai_protocol = IPPROTO_TCP;
319        break;                                  _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  #else
379          if ((ts->HostName[0] >= 0x30) && (ts->HostName[0] <= 0x39))          if ((ts->HostName[0] >= 0x30) && (ts->HostName[0] <= 0x39))
380          {          {
# Line 467  void CommOpen(HWND HW, PTTSet ts, PComVa Line 470  void CommOpen(HWND HW, PTTSet ts, PComVa
470        break;        break;
471  #endif /* NO_INET6 */  #endif /* NO_INET6 */
472    
473      case IdSerial:                  case IdSerial:
474        InitFileIO(IdSerial);  /* TTPLUG */                          InitFileIO(IdSerial);  /* TTPLUG */
475        TTXOpenFile(); /* TTPLUG */                          TTXOpenFile(); /* TTPLUG */
476        _snprintf_s(P, sizeof(P), _TRUNCATE, "COM%d", ts->ComPort);                          _snprintf_s(P, sizeof(P), _TRUNCATE, "COM%d", ts->ComPort);
477        strncpy_s(ErrMsg, sizeof(ErrMsg),P, _TRUNCATE);                          strncpy_s(ErrMsg, sizeof(ErrMsg),P, _TRUNCATE);
478        strncpy_s(P, sizeof(P),"\\\\.\\", _TRUNCATE);                          strncpy_s(P, sizeof(P),"\\\\.\\", _TRUNCATE);
479        strncat_s(P, sizeof(P),ErrMsg, _TRUNCATE);                          strncat_s(P, sizeof(P),ErrMsg, _TRUNCATE);
480        cv->ComID =                          cv->ComID =
481          PCreateFile(P,GENERIC_READ | GENERIC_WRITE,                          PCreateFile(P,GENERIC_READ | GENERIC_WRITE,
482                     0,NULL,OPEN_EXISTING,                                      0,NULL,OPEN_EXISTING,
483                     FILE_FLAG_OVERLAPPED,NULL);                                      FILE_FLAG_OVERLAPPED,NULL);
484        if (cv->ComID == INVALID_HANDLE_VALUE )                          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          get_lang_msg("MSG_CANTOEPN_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s", ts->UILanguageFile);  
488          _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4]);                                  if (cv->NoMsg==0) {
489                                            get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
490          if (cv->NoMsg==0)                                          MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
491          {                                  }
492            get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                  InvalidHost = TRUE;
493            MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                          }
494          }                          else {
495          InvalidHost = TRUE;                                  cv->Open = TRUE;
496        }                                  cv->ComPort = ts->ComPort;
497        else {                                  CommResetSerial(ts, cv, ts->ClearComBuffOnOpen);
498          cv->Open = TRUE;                                  if (!ts->ClearComBuffOnOpen) {
499          cv->ComPort = ts->ComPort;                                          cv->RRQ = TRUE;
500          CommResetSerial(ts, cv, ts->ClearComBuffOnOpen);                                  }
501          if (!ts->ClearComBuffOnOpen)  
502            cv->RRQ = TRUE;                                  /* notify to VT window that Comm Port is open */
503                                    PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);
504          /* notify to VT window that Comm Port is open */                                  InvalidHost = FALSE;
505          PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);  
506          InvalidHost = FALSE;                                  SetCOMFlag(ts->ComPort);
507                            }
508          SetCOMFlag(ts->ComPort);                          break; /* end of "case IdSerial:" */
509        }  
510        break; /* end of "case IdSerial:" */                  case IdFile:
511                            InitFileIO(IdFile);  /* TTPLUG */
512      case IdFile:                          TTXOpenFile(); /* TTPLUG */
513        InitFileIO(IdFile);  /* TTPLUG */                          cv->ComID = PCreateFile(ts->HostName,GENERIC_READ,0,NULL,
514        TTXOpenFile(); /* TTPLUG */                                                  OPEN_EXISTING,0,NULL);
515        cv->ComID = PCreateFile(ts->HostName,GENERIC_READ,0,NULL,                          InvalidHost = (cv->ComID == INVALID_HANDLE_VALUE);
516                               OPEN_EXISTING,0,NULL);                          if (InvalidHost) {
517        InvalidHost = (cv->ComID == INVALID_HANDLE_VALUE);                                  if (cv->NoMsg==0) {
518        if (InvalidHost)                                          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          if (cv->NoMsg==0)                                          MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
521          {                                  }
522            get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                          }
523            get_lang_msg("MSG_CANTOEPN_FILE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open file", ts->UILanguageFile);                          else {
524            MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                                  cv->Open = TRUE;
525          }                                  PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);
526        }                          }
527        else {                          break;
528          cv->Open = TRUE;          } /* end of "switch" */
         PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);  
       }  
       break;  
   } /* end of "switch" */  
529    
530  #ifndef NO_INET6  #ifndef NO_INET6
531  BreakSC:  BreakSC:
532  #endif /* NO_INET6 */  #endif /* NO_INET6 */
533    if (InvalidHost)          if (InvalidHost) {
534    {                  PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
535      PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);                  if ( (ts->PortType==IdTCPIP) && cv->Open ) {
536      if ( (ts->PortType==IdTCPIP) && cv->Open )                          if ( cv->s!=INVALID_SOCKET ) {
537      {                                  Pclosesocket(cv->s);
538        if ( cv->s!=INVALID_SOCKET ) Pclosesocket(cv->s);                          }
539        FreeWinsock();                          FreeWinsock();
540      }                  }
541      return;                  return;
542    }          }
543  }  }
544    
545  void CommThread(void *arg)  void CommThread(void *arg)
546  {  {
547    DWORD Evt;          DWORD Evt;
548    PComVar cv = (PComVar)arg;          PComVar cv = (PComVar)arg;
549    DWORD DErr;          DWORD DErr;
550    HANDLE REnd;          HANDLE REnd;
551    char Temp[20];          char Temp[20];
552    
553    _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);          _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
554    REnd = OpenEvent(EVENT_ALL_ACCESS,FALSE, Temp);          REnd = OpenEvent(EVENT_ALL_ACCESS,FALSE, Temp);
555    while (TRUE) {          while (TRUE) {
556      if (WaitCommEvent(cv->ComID,&Evt,NULL))                  if (WaitCommEvent(cv->ComID,&Evt,NULL)) {
557      {                          if (! cv->Ready) {
558        if (! cv->Ready) _endthread();                                  _endthread();
559        if (! cv->RRQ)                          }
560          PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_READ);                          if (! cv->RRQ) {
561        WaitForSingleObject(REnd,INFINITE);                                  PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_READ);
562      }                          }
563      else {                          WaitForSingleObject(REnd,INFINITE);
564        if (! cv->Ready) _endthread();                  }
565        ClearCommError(cv->ComID,&DErr,NULL);                  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)  void CommStart(PComVar cv, LONG lParam, PTTSet ts)
575  {  {
576    char ErrMsg[31];          char ErrMsg[31];
577    char Temp[20];          char Temp[20];
578    char uimsg[MAX_UIMSG];          char uimsg[MAX_UIMSG];
579    
580    if (! cv->Open ) return;          if (! cv->Open ) {
581    if ( cv->Ready ) return;                  return;
582            }
583    // キャンセルタイマがあれば取り消す。ただし、この時点で WM_TIMER が送られている可能性はある。          if ( cv->Ready ) {
584    if (*cv->ConnetingTimeout > 0) {                  return;
         KillTimer(cv->HWin, IdCancelConnectTimer);  
   }  
   
   switch (cv->PortType) {  
     case IdTCPIP:  
       ErrMsg[0] = 0;  
       switch (HIWORD(lParam)) {  
         case WSAECONNREFUSED:  
           get_lang_msg("MSG_COMM_REFUSE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection refused", ts->UILanguageFile);  
           _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);  
           break;  
         case WSAENETUNREACH:  
           get_lang_msg("MSG_COMM_REACH_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Network cannot be reached", ts->UILanguageFile);  
           _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);  
           break;  
         case WSAETIMEDOUT:  
           get_lang_msg("MSG_COMM_CONNECT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection timed out", ts->UILanguageFile);  
           _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);  
           break;  
         default:  
           get_lang_msg("MSG_COMM_TIMEOUT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot connect the host", ts->UILanguageFile);  
           _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);  
       }  
       if (HIWORD(lParam)>0)  
       {  
 #ifndef NO_INET6  
         /* connect() failed */  
         if (cv->res->ai_next != NULL) {  
           /* try to connect with other protocol */  
           CloseSocket(cv->s);  
           for (cv->res = cv->res->ai_next; cv->res; cv->res = cv->res->ai_next) {  
             cv->s = OpenSocket(cv);  
             if (cv->s == INVALID_SOCKET) {  
               CloseSocket(cv->s);  
               continue;  
             }  
             AsyncConnect(cv);  
             cv->Ready = FALSE;  
             cv->RetryWithOtherProtocol = TRUE; /* retry with other procotol */  
             return;  
           }  
         } else {  
           /* trying with all protocol family are failed */  
           if (cv->NoMsg==0)  
           {  
             get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);  
             MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);  
           }  
           PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);  
           cv->RetryWithOtherProtocol = FALSE;  
           return;  
585          }          }
586    
587            // キャンセルタイマがあれば取り消す。ただし、この時点で WM_TIMER が送られている可能性はある。
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  #else
641          if (cv->NoMsg==0)          if (cv->NoMsg==0)
642            MessageBox(cv->HWin,ErrMsg,ErrorCaption,            MessageBox(cv->HWin,ErrMsg,ErrorCaption,
# Line 638  void CommStart(PComVar cv, LONG lParam, Line 644  void CommStart(PComVar cv, LONG lParam,
644          PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);          PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
645          return;          return;
646  #endif /* NO_INET6 */  #endif /* NO_INET6 */
647        }                          }
648    
649  #ifndef NO_INET6  #ifndef NO_INET6
650        /* here is connection established */                          /* here is connection established */
651        cv->RetryWithOtherProtocol = FALSE;                          cv->RetryWithOtherProtocol = FALSE;
652  #endif /* NO_INET6 */  #endif /* NO_INET6 */
653        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);
654        TCPIPClosed = FALSE;                          TCPIPClosed = FALSE;
655        break;                          break;
656    
657      case IdSerial:                  case IdSerial:
658        _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);                          _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
659        ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp);                          ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp);
660        _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort);                          _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort);
661        memset(&wol,0,sizeof(OVERLAPPED));                          memset(&wol,0,sizeof(OVERLAPPED));
662        wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp);                          wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp);
663        _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort);                          _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort);
664        memset(&rol,0,sizeof(OVERLAPPED));                          memset(&rol,0,sizeof(OVERLAPPED));
665        rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp);                          rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp);
666    
667        /* create the receiver thread */                          /* create the receiver thread */
668        if (_beginthread(CommThread,0,cv) == -1)                          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", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);                                  get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile);
671          get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile);                                  MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
672          MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);                          }
673        }                          break;
674        break;  
675                    case IdFile:
676      case IdFile:                          cv->RRQ = TRUE;
677        cv->RRQ = TRUE;                          break;
678        break;          }
679    }          cv->Ready = TRUE;
   cv->Ready = TRUE;  
680  }  }
681    
682  BOOL CommCanClose(PComVar cv)  BOOL CommCanClose(PComVar cv)
683  { // check if data remains in buffer  { // check if data remains in buffer
684    if (! cv->Open) return TRUE;          if (! cv->Open) {
685    if (cv->InBuffCount>0) return FALSE;                  return TRUE;
686    if ((cv->HLogBuf!=NULL) &&          }
687        ((cv->LCount>0) ||          if (cv->InBuffCount>0) {
688         (cv->DCount>0))) return FALSE;                  return FALSE;
689    if ((cv->HBinBuf!=NULL) &&          }
690        (cv->BCount>0)) return FALSE;          if ((cv->HLogBuf!=NULL) &&
691    return TRUE;              ((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)  void CommClose(PComVar cv)
703  {  {
704    if ( ! cv->Open ) return;          if ( ! cv->Open ) {
705    cv->Open = FALSE;                  return;
706            }
707            cv->Open = FALSE;
708    
709    /* disable event message posting & flush buffer */          /* disable event message posting & flush buffer */
710    cv->RRQ = FALSE;          cv->RRQ = FALSE;
711    cv->Ready = FALSE;          cv->Ready = FALSE;
712    cv->InPtr = 0;          cv->InPtr = 0;
713    cv->InBuffCount = 0;          cv->InBuffCount = 0;
714    cv->OutPtr = 0;          cv->OutPtr = 0;
715    cv->OutBuffCount = 0;          cv->OutBuffCount = 0;
716    
717    /* close port & release resources */          /* close port & release resources */
718    switch (cv->PortType) {          switch (cv->PortType) {
719      case IdTCPIP:                  case IdTCPIP:
720        if (HAsync!=0)                          if (HAsync!=0) {
721          PWSACancelAsyncRequest(HAsync);                                  PWSACancelAsyncRequest(HAsync);
722        HAsync = 0;                          }
723                            HAsync = 0;
724  #ifndef NO_INET6  #ifndef NO_INET6
725        freeaddrinfo(cv->res0);                          freeaddrinfo(cv->res0);
726  #endif /* NO_INET6 */  #endif /* NO_INET6 */
727        if ( cv->s!=INVALID_SOCKET )                          if ( cv->s!=INVALID_SOCKET ) {
728          Pclosesocket(cv->s);                                  Pclosesocket(cv->s);
729        cv->s = INVALID_SOCKET;                          }
730        TTXCloseTCP(); /* TTPLUG */                          cv->s = INVALID_SOCKET;
731        FreeWinsock();                          TTXCloseTCP(); /* TTPLUG */
732        break;                          FreeWinsock();
733      case IdSerial:                          break;
734        if ( cv->ComID != INVALID_HANDLE_VALUE )                  case IdSerial:
735        {                          if ( cv->ComID != INVALID_HANDLE_VALUE ) {
736          CloseHandle(ReadEnd);                                  CloseHandle(ReadEnd);
737          CloseHandle(wol.hEvent);                                  CloseHandle(wol.hEvent);
738          CloseHandle(rol.hEvent);                                  CloseHandle(rol.hEvent);
739          PurgeComm(cv->ComID,                                  PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT |
740                    PURGE_TXABORT | PURGE_RXABORT |                                                       PURGE_TXCLEAR | PURGE_RXCLEAR);
741                    PURGE_TXCLEAR | PURGE_RXCLEAR);                                  EscapeCommFunction(cv->ComID,CLRDTR);
742          EscapeCommFunction(cv->ComID,CLRDTR);                                  SetCommMask(cv->ComID,0);
743          SetCommMask(cv->ComID,0);                                  PCloseFile(cv->ComID);
744          PCloseFile(cv->ComID);                                  ClearCOMFlag(cv->ComPort);
745          ClearCOMFlag(cv->ComPort);                          }
746        }                          TTXCloseFile(); /* TTPLUG */
747        TTXCloseFile(); /* TTPLUG */                          break;
748        break;                  case IdFile:
749      case IdFile:                          if (cv->ComID != INVALID_HANDLE_VALUE) {
750        if (cv->ComID != INVALID_HANDLE_VALUE)                                  PCloseFile(cv->ComID);
751          PCloseFile(cv->ComID);                          }
752        TTXCloseFile(); /* TTPLUG */                          TTXCloseFile(); /* TTPLUG */
753        break;                          break;
754    }          }
755    cv->ComID = INVALID_HANDLE_VALUE;          cv->ComID = INVALID_HANDLE_VALUE;
756    cv->PortType = 0;          cv->PortType = 0;
757  }  }
758    
759  void CommProcRRQ(PComVar cv)  void CommProcRRQ(PComVar cv)
760  {  {
761    if ( ! cv->Ready ) return;          if ( ! cv->Ready ) {
762    /* disable receive request */                  return;
763    switch (cv->PortType) {          }
764      case IdTCPIP:          /* disable receive request */
765        if (! TCPIPClosed)          switch (cv->PortType) {
766          PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_OOB | FD_CLOSE);                  case IdTCPIP:
767        break;                          if (! TCPIPClosed) {
768      case IdSerial:                                  PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_OOB | FD_CLOSE);
769        break;                          }
770    }                          break;
771    cv->RRQ = TRUE;                  case IdSerial:
772    CommReceive(cv);                          break;
773            }
774            cv->RRQ = TRUE;
775            CommReceive(cv);
776  }  }
777    
778  void CommReceive(PComVar cv)  void CommReceive(PComVar cv)
779  {  {
780    DWORD C;          DWORD C;
781    DWORD DErr;          DWORD DErr;
   
   if (! cv->Ready || ! cv->RRQ ||  
       (cv->InBuffCount>=InBuffSize)) return;  
782    
783    /* Compact buffer */          if (! cv->Ready || ! cv->RRQ ||
784    if ((cv->InBuffCount>0) && (cv->InPtr>0))              (cv->InBuffCount>=InBuffSize)) {
785    {                  return;
     memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount);  
     cv->InPtr = 0;  
   }  
   
   if (cv->InBuffCount<InBuffSize)  
   {  
     switch (cv->PortType) {  
       case IdTCPIP:  
         C = Precv(cv->s, &(cv->InBuff[cv->InBuffCount]),  
                  InBuffSize-cv->InBuffCount, 0);  
         if (C == SOCKET_ERROR)  
         {  
           C = 0;  
           PWSAGetLastError();  
         }  
         cv->InBuffCount = cv->InBuffCount + C;  
         break;  
       case IdSerial:  
         do {  
           ClearCommError(cv->ComID,&DErr,NULL);  
           if (! PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),  
             InBuffSize-cv->InBuffCount,&C,&rol))  
           {  
             if (GetLastError() == ERROR_IO_PENDING)  
             {  
               if (WaitForSingleObject(rol.hEvent, 1000) !=  
                   WAIT_OBJECT_0)  
                 C = 0;  
               else  
                 GetOverlappedResult(cv->ComID,&rol,&C,FALSE);  
             }  
             else  
               C = 0;  
           }  
           cv->InBuffCount = cv->InBuffCount + C;  
         } while ((C!=0) && (cv->InBuffCount<InBuffSize));  
         ClearCommError(cv->ComID,&DErr,NULL);  
         break;  
       case IdFile:  
         if (PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),  
           InBuffSize-cv->InBuffCount,&C,NULL))  
         {  
           if (C == 0) {  
             DErr = ERROR_HANDLE_EOF;  
           }  
           else {  
             cv->InBuffCount = cv->InBuffCount + C;  
           }  
786          }          }
787          else {  
788            DErr = GetLastError();          /* 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          break;  
794      }          if (cv->InBuffCount<InBuffSize) {
795    }                  switch (cv->PortType) {
796                            case IdTCPIP:
797    if (cv->InBuffCount==0) {                                  C = Precv(cv->s, &(cv->InBuff[cv->InBuffCount]),
798      switch (cv->PortType) {                                            InBuffSize-cv->InBuffCount, 0);
799        case IdTCPIP:                                  if (C == SOCKET_ERROR) {
800          if (! TCPIPClosed)                                          C = 0;
801            PWSAAsyncSelect(cv->s,cv->HWin,                                          PWSAGetLastError();
802              WM_USER_COMMNOTIFY, FD_READ | FD_OOB | FD_CLOSE);                                  }
803          break;                                  cv->InBuffCount = cv->InBuffCount + C;
804        case IdSerial:                                  break;
805          cv->RRQ = FALSE;                          case IdSerial:
806          SetEvent(ReadEnd);                                  do {
807          return;                                          ClearCommError(cv->ComID,&DErr,NULL);
808        case IdFile:                                          if (! PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),
809          if (DErr != ERROR_IO_PENDING) {                                                          InBuffSize-cv->InBuffCount,&C,&rol)) {
810            PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);                                                  if (GetLastError() == ERROR_IO_PENDING) {
811            cv->RRQ = FALSE;                                                          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          else {  
843            cv->RRQ = TRUE;          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          }          }
         return;  
     }  
     cv->RRQ = FALSE;  
   }  
867  }  }
868    
869  void CommSend(PComVar cv)  void CommSend(PComVar cv)
870  {  {
871    int delay;          int delay;
872    COMSTAT Stat;          COMSTAT Stat;
873    BYTE LineEnd;          BYTE LineEnd;
874    int C, D, Max;          int C, D, Max;
875    DWORD DErr;          DWORD DErr;
   
   if ((! cv->Open) || (! cv->Ready))  
   {  
     cv->OutBuffCount = 0;    
     return;  
   }  
   
   if ((cv->OutBuffCount == 0) || (! cv->CanSend)) return;  
   
   /* Max num of bytes to be written */  
   switch (cv->PortType) {  
     case IdTCPIP:  
       if (TCPIPClosed) cv->OutBuffCount = 0;  
       Max = cv->OutBuffCount;  
       break;  
     case IdSerial:  
       ClearCommError(cv->ComID,&DErr,&Stat);  
       Max = OutBuffSize - Stat.cbOutQue;  
       break;  
     case IdFile:  
       Max = cv->OutBuffCount;  
       break;  
   }  
876    
877    if ( Max<=0 ) return;          if ((! cv->Open) || (! cv->Ready)) {
878    if ( Max > cv->OutBuffCount ) Max = cv->OutBuffCount;                  cv->OutBuffCount = 0;  
879                    return;
880            }
881    
882    if (cv->PortType == IdTCPIP && cv->TelFlag) {          if ((cv->OutBuffCount == 0) || (! cv->CanSend)) {
883      cv->LastSendTime = time(NULL);                  return;
884    }          }
   
   C = Max;  
   delay = 0;  
   
   if ( cv->DelayFlag && (cv->PortType==IdSerial) )  
   {  
     if ( cv->DelayPerLine > 0 )  
     {  
       if ( cv->CRSend==IdCR ) LineEnd = 0x0d;  
                          else LineEnd = 0x0a;  
       C = 1;  
       if ( cv->DelayPerChar==0 )  
         while ((C<Max) && (cv->OutBuff[cv->OutPtr+C-1]!=LineEnd))  
           C++;  
       if ( cv->OutBuff[cv->OutPtr+C-1]==LineEnd )  
         delay = cv->DelayPerLine;  
       else delay = cv->DelayPerChar;  
     }  
     else if ( cv->DelayPerChar > 0 )  
     {  
       C = 1;  
       delay = cv->DelayPerChar;  
     }  
   }  
   
   /* Write to comm driver/Winsock */  
   switch (cv->PortType) {  
     case IdTCPIP:  
       D = Psend(cv->s, &(cv->OutBuff[cv->OutPtr]), C, 0);  
       if ( D==SOCKET_ERROR ) /* if error occurs */  
       {  
         PWSAGetLastError(); /* Clear error */  
         D = 0;  
       }  
       break;  
885    
886      case IdSerial:          /* Max num of bytes to be written */
887        if (! PWriteFile(cv->ComID,&(cv->OutBuff[cv->OutPtr]),C,(LPDWORD)&D,&wol))          switch (cv->PortType) {
888        {                  case IdTCPIP:
889          if (GetLastError() == ERROR_IO_PENDING)                          if (TCPIPClosed) {
890          {                                  cv->OutBuffCount = 0;
891            if (WaitForSingleObject(wol.hEvent,1000) !=                          }
892                WAIT_OBJECT_0)                          Max = cv->OutBuffCount;
893              D = C;      /* Time out, ignore data */                          break;
894            else                  case IdSerial:
895              GetOverlappedResult(cv->ComID,&wol,(LPDWORD)&D,FALSE);                          ClearCommError(cv->ComID,&DErr,&Stat);
896                            Max = OutBuffSize - Stat.cbOutQue;
897                            break;
898                    case IdFile:
899                            Max = cv->OutBuffCount;
900                            break;
901          }          }
         else /* I/O error */  
           D = C; /* ignore error */  
       }  
       ClearCommError(cv->ComID,&DErr,&Stat);  
       break;  
902    
903      case IdFile:          if ( Max<=0 ) {
904        if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) {                  return;
905          if (! GetLastError() == ERROR_IO_PENDING) {          }
906            D = C; /* ignore data */          if ( Max > cv->OutBuffCount ) {
907          }                  Max = cv->OutBuffCount;
908        }          }
909        break;  
910    }          if (cv->PortType == IdTCPIP && cv->TelFlag) {
911                    cv->LastSendTime = time(NULL);
912            }
913    
914            C = Max;
915            delay = 0;
916    
917    cv->OutBuffCount = cv->OutBuffCount - D;          if ( cv->DelayFlag && (cv->PortType==IdSerial) ) {
918    if ( cv->OutBuffCount==0 )                  if ( cv->DelayPerLine > 0 ) {
919      cv->OutPtr = 0;                          if ( cv->CRSend==IdCR ) {
920    else                                  LineEnd = 0x0d;
921      cv->OutPtr = cv->OutPtr + D;                          }
922                            else {
923    if ( (C==D) && (delay>0) )                                  LineEnd = 0x0a;
924    {                          }
925      cv->CanSend = FALSE;                          C = 1;
926      SetTimer(cv->HWin, IdDelayTimer, delay, NULL);                          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)  void CommSendBreak(PComVar cv)
995  /* for only serial ports */  /* for only serial ports */
996  {  {
997    MSG DummyMsg;          MSG DummyMsg;
   
   if ( ! cv->Ready ) return;  
   
   switch (cv->PortType) {  
     case IdSerial:  
       /* Set com port into a break state */  
       SetCommBreak(cv->ComID);  
998    
999        /* pause for 1 sec */          if ( ! cv->Ready ) {
1000        if (SetTimer(cv->HWin, IdBreakTimer, 1000, NULL) != 0)                  return;
1001          GetMessage(&DummyMsg,cv->HWin,WM_TIMER,WM_TIMER);          }
1002    
1003        /* Set com port into the nonbreak state */          switch (cv->PortType) {
1004        ClearCommBreak(cv->ComID);                  case IdSerial:
1005        break;                          /* 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)  void CommLock(PTTSet ts, PComVar cv, BOOL Lock)
1020  {  {
1021    BYTE b;          BYTE b;
1022    DWORD Func;          DWORD Func;
1023    
1024    if (! cv->Ready) return;          if (! cv->Ready) {
1025    if ((cv->PortType==IdTCPIP) ||                  return;
1026        (cv->PortType==IdSerial) &&          }
1027        (ts->Flow!=IdFlowHard))          if ((cv->PortType==IdTCPIP) ||
1028    {              (cv->PortType==IdSerial) &&
1029      if (Lock)              (ts->Flow!=IdFlowHard)) {
1030        b = XOFF;                  if (Lock) {
1031      else                          b = XOFF;
1032        b = XON;                  }
1033      CommBinaryOut(cv,&b,1);                  else {
1034    }                          b = XON;
1035    else if ((cv->PortType==IdSerial) &&                  }
1036             (ts->Flow==IdFlowHard))                  CommBinaryOut(cv,&b,1);
1037    {          }
1038      if (Lock)          else if ((cv->PortType==IdSerial) &&
1039        Func = CLRRTS;                   (ts->Flow==IdFlowHard)) {
1040      else                  if (Lock) {
1041        Func = SETRTS;                          Func = CLRRTS;
1042      EscapeCommFunction(cv->ComID,Func);                  }
1043    }                  else {
1044                            Func = SETRTS;
1045                    }
1046                    EscapeCommFunction(cv->ComID,Func);
1047            }
1048  }  }
1049    
1050  int GetCommSerialBaudRate(int id)  int GetCommSerialBaudRate(int id)
# Line 1022  int GetCommSerialBaudRate(int id) Line 1060  int GetCommSerialBaudRate(int id)
1060    
1061  BOOL PrnOpen(PCHAR DevName)  BOOL PrnOpen(PCHAR DevName)
1062  {  {
1063    char Temp[MAXPATHLEN];          char Temp[MAXPATHLEN];
1064    DCB dcb;          DCB dcb;
1065    DWORD DErr;          DWORD DErr;
1066    COMMTIMEOUTS ctmo;          COMMTIMEOUTS ctmo;
1067    
1068    strncpy_s(Temp, sizeof(Temp),DevName, _TRUNCATE);          strncpy_s(Temp, sizeof(Temp),DevName, _TRUNCATE);
1069    Temp[4] = 0; // COMn or LPTn          Temp[4] = 0; // COMn or LPTn
1070    LPTFlag = (Temp[0]=='L') ||          LPTFlag = (Temp[0]=='L') ||
1071              (Temp[0]=='l');                    (Temp[0]=='l');
1072    PrnID =          PrnID = CreateFile(Temp,GENERIC_WRITE,
1073      CreateFile(Temp,GENERIC_WRITE,                             0,NULL,OPEN_EXISTING,
1074                 0,NULL,OPEN_EXISTING,                             0,NULL);
1075                 0,NULL);          if (PrnID == INVALID_HANDLE_VALUE) {
1076    if (PrnID == INVALID_HANDLE_VALUE) return FALSE;                  return FALSE;
1077            }
1078    if (GetCommState(PrnID,&dcb))  
1079    {          if (GetCommState(PrnID,&dcb)) {
1080      BuildCommDCB(DevName,&dcb);                  BuildCommDCB(DevName,&dcb);
1081      SetCommState(PrnID,&dcb);                  SetCommState(PrnID,&dcb);
1082    }          }
1083    ClearCommError(PrnID,&DErr,NULL);          ClearCommError(PrnID,&DErr,NULL);
1084    if (! LPTFlag)          if (! LPTFlag) {
1085      SetupComm(PrnID,0,CommOutQueSize);                  SetupComm(PrnID,0,CommOutQueSize);
1086    /* flush output buffer */          }
1087    PurgeComm(PrnID, PURGE_TXABORT |          /* flush output buffer */
1088      PURGE_TXCLEAR);          PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR);
1089    memset(&ctmo,0,sizeof(ctmo));          memset(&ctmo,0,sizeof(ctmo));
1090    ctmo.WriteTotalTimeoutConstant = 1000;          ctmo.WriteTotalTimeoutConstant = 1000;
1091    SetCommTimeouts(PrnID,&ctmo);          SetCommTimeouts(PrnID,&ctmo);
1092    if (! LPTFlag)          if (! LPTFlag) {
1093      EscapeCommFunction(PrnID,SETDTR);                  EscapeCommFunction(PrnID,SETDTR);
1094    return TRUE;          }
1095            return TRUE;
1096  }  }
1097    
1098  int PrnWrite(PCHAR b, int c)  int PrnWrite(PCHAR b, int c)
1099  {  {
1100    int d;          int d;
1101    DWORD DErr;          DWORD DErr;
1102    COMSTAT Stat;          COMSTAT Stat;
1103    
1104    if (PrnID == INVALID_HANDLE_VALUE )          if (PrnID == INVALID_HANDLE_VALUE ) {
1105      return c;                  return c;
1106            }
1107    ClearCommError(PrnID,&DErr,&Stat);  
1108    if (! LPTFlag &&          ClearCommError(PrnID,&DErr,&Stat);
1109        (OutBuffSize - (int)Stat.cbOutQue < c))          if (! LPTFlag &&
1110      c = OutBuffSize - Stat.cbOutQue;                  (OutBuffSize - (int)Stat.cbOutQue < c)) {
1111    if (c<=0) return 0;                  c = OutBuffSize - Stat.cbOutQue;
1112    if (! WriteFile(PrnID,b,c,(LPDWORD)&d,NULL))          }
1113      d = 0;          if (c<=0) {
1114    ClearCommError(PrnID,&DErr,NULL);                  return 0;
1115    return d;          }
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()  void PrnCancel()
1124  {  {
1125    PurgeComm(PrnID,          PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR);
1126      PURGE_TXABORT | PURGE_TXCLEAR);          PrnClose();
   PrnClose();  
1127  }  }
1128    
1129  void PrnClose()  void PrnClose()
1130  {  {
1131    if (PrnID != INVALID_HANDLE_VALUE)          if (PrnID != INVALID_HANDLE_VALUE) {
1132    {                  if (!LPTFlag) {
1133      if (!LPTFlag)                          EscapeCommFunction(PrnID,CLRDTR);
1134        EscapeCommFunction(PrnID,CLRDTR);                  }
1135      CloseHandle(PrnID);                  CloseHandle(PrnID);
1136    }          }
1137    PrnID = INVALID_HANDLE_VALUE;          PrnID = INVALID_HANDLE_VALUE;
1138  }  }

Legend:
Removed from v.3268  
changed lines
  Added in v.3393

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