Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8051 - (hide annotations) (download) (as text)
Sat Aug 31 08:29:39 2019 UTC (4 years, 6 months ago) by yutakapon
Original Path: trunk/teraterm/teraterm/commlib.c
File MIME type: text/x-csrc
File size: 35794 byte(s)
シリアル接続のハードウェアフロー制御に DSR/DTR を追加した。

branches/flowctrl_dsrdtrからリビジョン7825-7827をマージ:
シリアル接続のハードウェアフロー制御に DSR/DTR を追加した。
4つの選択項目が一度に表示されるように、シリアルポート設定ダイアログのコンボボックスの高さを調整した。
#39365
........
シリアル接続のハードウェアフロー制御の設定項目にコメントを追加した。
デフォルト値は以前と変わらない。
#39365

........
ドキュメントを更新した。
#39365

........

1 doda 6806 /*
2     * Copyright (C) 1994-1998 T. Teranishi
3     * (C) 2005-2017 TeraTerm Project
4     * All rights reserved.
5     *
6 doda 6841 * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9 doda 6806 *
10 doda 6841 * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17 doda 6806 *
18 doda 6841 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 doda 6806 */
29 maya 3857 /* IPv6 modification is Copyright (C) 2000, 2001 Jun-ya KATO <kato@win6.jp> */
30    
31     /* TERATERM.EXE, Communication routines */
32     #include "teraterm.h"
33     #include "tttypes.h"
34     #include "tt_res.h"
35     #include <process.h>
36    
37     #include "ttcommon.h"
38     #include "ttwsk.h"
39     #include "ttlib.h"
40     #include "ttfileio.h"
41     #include "ttplug.h" /* TTPLUG */
42    
43     #include "commlib.h"
44     #include <winsock2.h>
45     #include <ws2tcpip.h>
46     #include <stdio.h> /* for _snprintf() */
47     #include <time.h>
48 doda 3932 #include <locale.h>
49 maya 3857
50     static SOCKET OpenSocket(PComVar);
51     static void AsyncConnect(PComVar);
52     static int CloseSocket(SOCKET);
53    
54     /* create socket */
55     static SOCKET OpenSocket(PComVar cv)
56     {
57     cv->s = cv->res->ai_family;
58     cv->s = Psocket(cv->res->ai_family, cv->res->ai_socktype, cv->res->ai_protocol);
59     return cv->s;
60     }
61    
62     /* connect with asynchronous mode */
63     static void AsyncConnect(PComVar cv)
64     {
65     int Err;
66     BOOL BBuf;
67     BBuf = TRUE;
68     /* set synchronous mode */
69     PWSAAsyncSelect(cv->s,cv->HWin,0,0);
70 doda 6801 Psetsockopt(cv->s,(int)SOL_SOCKET,SO_OOBINLINE,(char *)&BBuf,sizeof(BBuf));
71 maya 3857 /* set asynchronous mode */
72     PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMOPEN, FD_CONNECT);
73    
74     // �z�X�g���������������������������A�����I���\�P�b�g���N���[�Y�����A
75     // �����������L�����Z���������B�l��0�������������������B
76     // (2007.1.11 yutaka)
77     if (*cv->ConnetingTimeout > 0) {
78     SetTimer(cv->HWin, IdCancelConnectTimer, *cv->ConnetingTimeout * 1000, NULL);
79     }
80    
81     /* WM_USER_COMMOPEN occurs, CommOpen is called, then CommStart is called */
82     Err = Pconnect(cv->s, cv->res->ai_addr, cv->res->ai_addrlen);
83     if (Err != 0) {
84     Err = PWSAGetLastError();
85     if (Err == WSAEWOULDBLOCK) {
86     /* Do nothing */
87     } else if (Err!=0 ) {
88     PostMessage(cv->HWin, WM_USER_COMMOPEN,0,
89     MAKELONG(FD_CONNECT,Err));
90     }
91     }
92     }
93    
94     /* close socket */
95     static int CloseSocket(SOCKET s)
96     {
97     return Pclosesocket(s);
98     }
99    
100     #define CommInQueSize 8192
101     #define CommOutQueSize 2048
102     #define CommXonLim 2048
103     #define CommXoffLim 2048
104    
105     #define READENDNAME "ReadEnd"
106     #define WRITENAME "Write"
107     #define READNAME "Read"
108     #define PRNWRITENAME "PrnWrite"
109    
110     static HANDLE ReadEnd;
111     static OVERLAPPED wol, rol;
112    
113     // Winsock async operation handle
114     static HANDLE HAsync=0;
115    
116     BOOL TCPIPClosed = TRUE;
117    
118     /* Printer port handle for
119     direct pass-thru printing */
120     static HANDLE PrnID = INVALID_HANDLE_VALUE;
121     static BOOL LPTFlag;
122    
123     // Initialize ComVar.
124     // This routine is called only once
125     // by the initialization procedure of Tera Term.
126     void CommInit(PComVar cv)
127     {
128     cv->Open = FALSE;
129     cv->Ready = FALSE;
130    
131     // log-buffer variables
132     cv->HLogBuf = 0;
133     cv->HBinBuf = 0;
134     cv->LogBuf = NULL;
135     cv->BinBuf = NULL;
136     cv->LogPtr = 0;
137     cv->LStart = 0;
138     cv->LCount = 0;
139     cv->BinPtr = 0;
140     cv->BStart = 0;
141     cv->BCount = 0;
142     cv->DStart = 0;
143     cv->DCount = 0;
144     cv->BinSkip = 0;
145     cv->FilePause = 0;
146     cv->ProtoFlag = FALSE;
147     /* message flag */
148     cv->NoMsg = 0;
149 doda 6662
150 doda 6788 cv->isSSH = 0;
151     cv->TitleRemote[0] = '\0';
152    
153 doda 6662 cv->NotifyIcon = NULL;
154 doda 6947
155     cv->ConnectedTime = 0;
156 maya 3857 }
157    
158     /* reset a serial port which is already open */
159     void CommResetSerial(PTTSet ts, PComVar cv, BOOL ClearBuff)
160     {
161     DCB dcb;
162     DWORD DErr;
163     COMMTIMEOUTS ctmo;
164    
165     if (! cv->Open ||
166     (cv->PortType != IdSerial)) {
167     return;
168     }
169    
170     ClearCommError(cv->ComID,&DErr,NULL);
171     SetupComm(cv->ComID,CommInQueSize,CommOutQueSize);
172     /* flush input and output buffers */
173     if (ClearBuff) {
174     PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT |
175     PURGE_TXCLEAR | PURGE_RXCLEAR);
176     }
177    
178     memset(&ctmo,0,sizeof(ctmo));
179     ctmo.ReadIntervalTimeout = MAXDWORD;
180     ctmo.WriteTotalTimeoutConstant = 500;
181     SetCommTimeouts(cv->ComID,&ctmo);
182     cv->InBuffCount = 0;
183     cv->InPtr = 0;
184     cv->OutBuffCount = 0;
185     cv->OutPtr = 0;
186    
187     cv->DelayPerChar = ts->DelayPerChar;
188     cv->DelayPerLine = ts->DelayPerLine;
189    
190     memset(&dcb,0,sizeof(DCB));
191     dcb.DCBlength = sizeof(DCB);
192 maya 3874 dcb.BaudRate = ts->Baud;
193 maya 3857 dcb.fBinary = TRUE;
194     switch (ts->Parity) {
195 doda 4849 case IdParityNone:
196     dcb.Parity = NOPARITY;
197     break;
198     case IdParityOdd:
199     dcb.fParity = TRUE;
200     dcb.Parity = ODDPARITY;
201     break;
202 maya 3857 case IdParityEven:
203     dcb.fParity = TRUE;
204     dcb.Parity = EVENPARITY;
205     break;
206 doda 4849 case IdParityMark:
207 maya 3857 dcb.fParity = TRUE;
208 doda 4849 dcb.Parity = MARKPARITY;
209 maya 3857 break;
210 doda 4849 case IdParitySpace:
211     dcb.fParity = TRUE;
212     dcb.Parity = SPACEPARITY;
213 maya 3857 break;
214     }
215    
216     dcb.fDtrControl = DTR_CONTROL_ENABLE;
217     dcb.fRtsControl = RTS_CONTROL_ENABLE;
218     switch (ts->Flow) {
219     case IdFlowX:
220     dcb.fOutX = TRUE;
221     dcb.fInX = TRUE;
222     dcb.XonLim = CommXonLim;
223     dcb.XoffLim = CommXoffLim;
224     dcb.XonChar = XON;
225     dcb.XoffChar = XOFF;
226     break;
227 yutakapon 8051 case IdFlowHard: // RTS/CTS
228 maya 3857 dcb.fOutxCtsFlow = TRUE;
229     dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
230     break;
231 yutakapon 8051 case IdFlowHardDsrDtr: // DSR/DTR
232     dcb.fOutxDsrFlow = TRUE;
233     dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
234     break;
235 maya 3857 }
236    
237     switch (ts->DataBit) {
238     case IdDataBit7:
239     dcb.ByteSize = 7;
240     break;
241     case IdDataBit8:
242     dcb.ByteSize = 8;
243     break;
244     }
245     switch (ts->StopBit) {
246     case IdStopBit1:
247     dcb.StopBits = ONESTOPBIT;
248     break;
249 doda 4849 case IdStopBit15:
250     dcb.StopBits = ONE5STOPBITS;
251     break;
252 maya 3857 case IdStopBit2:
253     dcb.StopBits = TWOSTOPBITS;
254     break;
255     }
256    
257     SetCommState(cv->ComID, &dcb);
258    
259     /* enable receive request */
260     SetCommMask(cv->ComID,0);
261     SetCommMask(cv->ComID,EV_RXCHAR);
262     }
263    
264 yutakapon 4860 // ���O�t���p�C�v�����������������`�F�b�N�����B
265     // \\ServerName\pipe\PipeName
266     //
267     // return 0: ������
268     // -1: �s��
269     // (2012.3.10 yutaka)
270     int CheckNamedPipeFormat(char *p, int size)
271     {
272     int ret = -1;
273     char *s;
274    
275     if (size <= 8)
276     goto error;
277    
278     if (p[0] == '\\' && p[1] == '\\') {
279     s = strchr(&p[2], '\\');
280     if (s && _strnicmp(s+1, "pipe\\", 5) == 0) {
281     ret = 0;
282     }
283     }
284    
285     error:
286     return (ret);
287     }
288    
289 maya 3857 void CommOpen(HWND HW, PTTSet ts, PComVar cv)
290     {
291 yutakapon 4857 char ErrMsg[21+256];
292     char P[50+256];
293 maya 3857
294     MSG Msg;
295     ADDRINFO hints;
296     char pname[NI_MAXSERV];
297    
298     BOOL InvalidHost;
299    
300     char uimsg[MAX_UIMSG];
301    
302 yutakapon 4860 // �z�X�g�������O�t���p�C�v�����������������B
303     if (ts->PortType == IdTCPIP) {
304     if (CheckNamedPipeFormat(ts->HostName, strlen(ts->HostName)) == 0) {
305     ts->PortType = IdNamedPipe;
306     }
307     }
308    
309 maya 3857 /* initialize ComVar */
310     cv->InBuffCount = 0;
311     cv->InPtr = 0;
312     cv->OutBuffCount = 0;
313     cv->OutPtr = 0;
314     cv->HWin = HW;
315     cv->Ready = FALSE;
316     cv->Open = FALSE;
317     cv->PortType = ts->PortType;
318     cv->ComPort = 0;
319     cv->RetryCount = 0;
320     cv->RetryWithOtherProtocol = TRUE;
321     cv->s = INVALID_SOCKET;
322     cv->ComID = INVALID_HANDLE_VALUE;
323     cv->CanSend = TRUE;
324     cv->RRQ = FALSE;
325     cv->SendKanjiFlag = FALSE;
326     cv->SendCode = IdASCII;
327     cv->EchoKanjiFlag = FALSE;
328     cv->EchoCode = IdASCII;
329     cv->Language = ts->Language;
330     cv->CRSend = ts->CRSend;
331     cv->KanjiCodeEcho = ts->KanjiCode;
332     cv->JIS7KatakanaEcho = ts->JIS7Katakana;
333     cv->KanjiCodeSend = ts->KanjiCodeSend;
334     cv->JIS7KatakanaSend = ts->JIS7KatakanaSend;
335     cv->KanjiIn = ts->KanjiIn;
336     cv->KanjiOut = ts->KanjiOut;
337     cv->RussHost = ts->RussHost;
338     cv->RussClient = ts->RussClient;
339     cv->DelayFlag = TRUE;
340     cv->DelayPerChar = ts->DelayPerChar;
341     cv->DelayPerLine = ts->DelayPerLine;
342     cv->TelBinRecv = FALSE;
343     cv->TelBinSend = FALSE;
344     cv->TelFlag = FALSE;
345     cv->TelMode = FALSE;
346     cv->IACFlag = FALSE;
347     cv->TelCRFlag = FALSE;
348     cv->TelCRSend = FALSE;
349     cv->TelCRSendEcho = FALSE;
350     cv->TelAutoDetect = ts->TelAutoDetect; /* TTPLUG */
351     cv->Locale = ts->Locale;
352 doda 3932 cv->locale = _create_locale(LC_ALL, cv->Locale);
353 maya 3857 cv->CodePage = &ts->CodePage;
354     cv->ConnetingTimeout = &ts->ConnectingTimeout;
355     cv->LastSendTime = time(NULL);
356     cv->LineModeBuffCount = 0;
357     cv->Flush = FALSE;
358     cv->FlushLen = 0;
359     cv->TelLineMode = FALSE;
360 doda 6947 cv->ConnectedTime = 0;
361 maya 3857
362     if ((ts->PortType!=IdSerial) && (strlen(ts->HostName)==0))
363     {
364     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
365     return;
366     }
367    
368     switch (ts->PortType) {
369     case IdTCPIP:
370     cv->TelFlag = (ts->Telnet > 0);
371     if (ts->EnableLineMode) {
372     cv->TelLineMode = TRUE;
373     }
374     if (! LoadWinsock()) {
375     if (cv->NoMsg==0) {
376     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
377     get_lang_msg("MSG_WINSOCK_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot use winsock", ts->UILanguageFile);
378     MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
379     }
380     InvalidHost = TRUE;
381     }
382     else {
383     TTXOpenTCP(); /* TTPLUG */
384     cv->Open = TRUE;
385     /* resolving address */
386     memset(&hints, 0, sizeof(hints));
387     hints.ai_family = ts->ProtocolFamily;
388     hints.ai_socktype = SOCK_STREAM;
389     hints.ai_protocol = IPPROTO_TCP;
390     _snprintf_s(pname, sizeof(pname), _TRUNCATE, "%d", ts->TCPPort);
391    
392 doda 4089 HAsync = PWSAAsyncGetAddrInfo(HW, WM_USER_GETHOST,
393 maya 3857 ts->HostName, pname, &hints, &cv->res0);
394     if (HAsync == 0)
395     InvalidHost = TRUE;
396     else {
397     cv->ComPort = 1; // set "getting host" flag
398     // (see CVTWindow::OnSysCommand())
399     do {
400     if (GetMessage(&Msg,0,0,0)) {
401     if ((Msg.hwnd==HW) &&
402     ((Msg.message == WM_SYSCOMMAND) &&
403     ((Msg.wParam & 0xfff0) == SC_CLOSE) ||
404     (Msg.message == WM_COMMAND) &&
405     (LOWORD(Msg.wParam) == ID_FILE_EXIT) ||
406     (Msg.message == WM_CLOSE))) { /* Exit when the user closes Tera Term */
407     PWSACancelAsyncRequest(HAsync);
408     CloseHandle(HAsync);
409     HAsync = 0;
410     cv->ComPort = 0; // clear "getting host" flag
411     PostMessage(HW,Msg.message,Msg.wParam,Msg.lParam);
412     return;
413     }
414     if (Msg.message != WM_USER_GETHOST) { /* Prosess messages */
415     TranslateMessage(&Msg);
416     DispatchMessage(&Msg);
417     }
418     }
419     else {
420     return;
421     }
422     } while (Msg.message!=WM_USER_GETHOST);
423     cv->ComPort = 0; // clear "getting host" flag
424     CloseHandle(HAsync);
425     HAsync = 0;
426     InvalidHost = WSAGETASYNCERROR(Msg.lParam) != 0;
427     }
428     } /* if (!LoadWinsock()) */
429    
430     if (InvalidHost) {
431     if (cv->NoMsg==0) {
432     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
433     get_lang_msg("MSG_INVALID_HOST_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Invalid host", ts->UILanguageFile);
434     MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
435     }
436     goto BreakSC;
437     }
438     for (cv->res = cv->res0; cv->res; cv->res = cv->res->ai_next) {
439     cv->s = OpenSocket(cv);
440     if (cv->s == INVALID_SOCKET) {
441     CloseSocket(cv->s);
442     continue;
443     }
444     /* start asynchronous connect */
445     AsyncConnect(cv);
446     break; /* break for-loop immediately */
447     }
448     break;
449    
450     case IdSerial:
451     InitFileIO(IdSerial); /* TTPLUG */
452     TTXOpenFile(); /* TTPLUG */
453     _snprintf_s(P, sizeof(P), _TRUNCATE, "COM%d", ts->ComPort);
454     strncpy_s(ErrMsg, sizeof(ErrMsg),P, _TRUNCATE);
455     strncpy_s(P, sizeof(P),"\\\\.\\", _TRUNCATE);
456     strncat_s(P, sizeof(P),ErrMsg, _TRUNCATE);
457 doda 6893 cv->ComID = PCreateFile(P, GENERIC_READ | GENERIC_WRITE, 0, NULL,
458     OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
459 maya 3857 if (cv->ComID == INVALID_HANDLE_VALUE ) {
460 doda 6893 DWORD err = GetLastError();
461 maya 3857
462 doda 6893 switch (err) {
463     case ERROR_FILE_NOT_FOUND:
464     get_lang_msg("MSG_CANTOPEN_ERROR_NOTFOUND", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Not found.", ts->UILanguageFile);
465     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4]);
466     break;
467     case ERROR_ACCESS_DENIED:
468     get_lang_msg("MSG_CANTOPEN_ERROR_DENIED", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Access denied.", ts->UILanguageFile);
469     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4]);
470     break;
471     default:
472     get_lang_msg("MSG_CANTOPEN_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. (0x%08x)", ts->UILanguageFile);
473     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4], err);
474     break;
475     }
476    
477 maya 3857 if (cv->NoMsg==0) {
478     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
479     MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
480     }
481     InvalidHost = TRUE;
482     }
483     else {
484     cv->Open = TRUE;
485     cv->ComPort = ts->ComPort;
486     CommResetSerial(ts, cv, ts->ClearComBuffOnOpen);
487     if (!ts->ClearComBuffOnOpen) {
488     cv->RRQ = TRUE;
489     }
490    
491     /* notify to VT window that Comm Port is open */
492     PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);
493     InvalidHost = FALSE;
494    
495     SetCOMFlag(ts->ComPort);
496     }
497     break; /* end of "case IdSerial:" */
498    
499     case IdFile:
500     InitFileIO(IdFile); /* TTPLUG */
501     TTXOpenFile(); /* TTPLUG */
502 doda 6893 cv->ComID = PCreateFile(ts->HostName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
503 maya 3857 InvalidHost = (cv->ComID == INVALID_HANDLE_VALUE);
504     if (InvalidHost) {
505     if (cv->NoMsg==0) {
506     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
507 doda 6892 get_lang_msg("MSG_CANTOPEN_FILE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open file", ts->UILanguageFile);
508 maya 3857 MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
509     }
510     }
511     else {
512     cv->Open = TRUE;
513     PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);
514     }
515     break;
516 yutakapon 4857
517     case IdNamedPipe:
518     InitFileIO(IdNamedPipe); /* TTPLUG */
519     TTXOpenFile(); /* TTPLUG */
520 doda 6435
521 yutakapon 4858 memset(P, 0, sizeof(P));
522 yutakapon 4857 strncpy_s(P, sizeof(P), ts->HostName, _TRUNCATE);
523 yutakapon 4858
524     // ���O�t���p�C�v�����������������`�F�b�N�����B
525 yutakapon 4860 if (CheckNamedPipeFormat(P, strlen(P)) < 0) {
526     InvalidHost = TRUE;
527    
528 doda 6435 _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE,
529 yutakapon 5921 "Invalid pipe name (%d)\n\n"
530 yutakapon 4858 "A valid pipe name has the form\n"
531 doda 6435 "\"\\\\<ServerName>\\pipe\\<PipeName>\"",
532 yutakapon 4860 GetLastError());
533 yutakapon 4858 get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
534     MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
535     break;
536     }
537    
538 doda 6893 cv->ComID = PCreateFile(P, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
539     0, // �u���b�L���O���[�h������(FILE_FLAG_OVERLAPPED ���w��������)
540     NULL);
541 yutakapon 4857 if (cv->ComID == INVALID_HANDLE_VALUE ) {
542 doda 6893 DWORD err = GetLastError();
543 yutakapon 4857
544 doda 6893 switch (err) {
545     case ERROR_FILE_NOT_FOUND:
546     get_lang_msg("MSG_CANTOPEN_ERROR_NOTFOUND", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Not found.", ts->UILanguageFile);
547 doda 6894 _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, P);
548 doda 6893 break;
549     case ERROR_ACCESS_DENIED:
550     get_lang_msg("MSG_CANTOPEN_ERROR_DENIED", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Access denied.", ts->UILanguageFile);
551 doda 6894 _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, P);
552 doda 6893 break;
553 doda 6895 case ERROR_PIPE_BUSY:
554     get_lang_msg("MSG_CANTOPEN_ERROR_PIPEBUSY", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. Pipe is busy.", ts->UILanguageFile);
555     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, P);
556     break;
557 doda 6893 default:
558     get_lang_msg("MSG_CANTOPEN_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s. (0x%08x)", ts->UILanguageFile);
559 doda 6894 _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, P, err);
560 doda 6893 break;
561     }
562    
563 yutakapon 4857 if (cv->NoMsg==0) {
564     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
565     MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
566     }
567     InvalidHost = TRUE;
568     }
569     else {
570     cv->Open = TRUE;
571     PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0);
572     InvalidHost = FALSE;
573     }
574     break; /* end of "case IdNamedPipe:" */
575    
576 maya 3857 } /* end of "switch" */
577    
578     BreakSC:
579     if (InvalidHost) {
580     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
581     if ( (ts->PortType==IdTCPIP) && cv->Open ) {
582     if ( cv->s!=INVALID_SOCKET ) {
583     Pclosesocket(cv->s);
584 yutakapon 3968 cv->s = INVALID_SOCKET; /* �\�P�b�g�����������t�����B(2010.8.6 yutaka) */
585 maya 3857 }
586     FreeWinsock();
587     }
588     return;
589     }
590     }
591    
592 yutakapon 4857 // ���O�t���p�C�v�p�X���b�h
593     void NamedPipeThread(void *arg)
594     {
595     PComVar cv = (PComVar)arg;
596     DWORD DErr;
597     HANDLE REnd;
598     char Temp[20];
599     char Buffer[1]; // 1byte
600     DWORD BytesRead, TotalBytesAvail, BytesLeftThisMessage;
601    
602     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
603     REnd = OpenEvent(EVENT_ALL_ACCESS,FALSE, Temp);
604     while (TRUE) {
605     BytesRead = 0;
606     // ���O�t���p�C�v���C�x���g���������������������d�l�������A�L���[�����g��
607     // �`���������������AReadFile() ���������������f�����B
608     if (PeekNamedPipe(cv->ComID, Buffer, sizeof(Buffer), &BytesRead, &TotalBytesAvail, &BytesLeftThisMessage)) {
609     if (! cv->Ready) {
610     _endthread();
611     }
612     if (BytesRead == 0) { // �����������A�����������B
613     Sleep(1);
614     continue;
615     }
616     if (! cv->RRQ) {
617     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_READ);
618     }
619     // ReadFile() ���I�������������B
620     WaitForSingleObject(REnd,INFINITE);
621     }
622     else {
623 doda 6435 DErr = GetLastError();
624 yutakapon 4962 // [VMware] this returns 109 (broken pipe) if a named pipe is removed.
625     // [Virtual Box] this returns 233 (pipe not connected) if a named pipe is removed.
626     if (! cv->Ready || ERROR_BROKEN_PIPE == DErr || ERROR_PIPE_NOT_CONNECTED == DErr) {
627 yutakapon 4863 PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
628 yutakapon 4857 _endthread();
629     }
630     }
631     }
632     }
633    
634 maya 3857 void CommThread(void *arg)
635     {
636     DWORD Evt;
637     PComVar cv = (PComVar)arg;
638     DWORD DErr;
639     HANDLE REnd;
640     char Temp[20];
641    
642     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
643     REnd = OpenEvent(EVENT_ALL_ACCESS,FALSE, Temp);
644     while (TRUE) {
645     if (WaitCommEvent(cv->ComID,&Evt,NULL)) {
646     if (! cv->Ready) {
647     _endthread();
648     }
649     if (! cv->RRQ) {
650     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_READ);
651     }
652     WaitForSingleObject(REnd,INFINITE);
653     }
654     else {
655     DErr = GetLastError(); // this returns 995 (operation aborted) if a USB com port is removed
656     if (! cv->Ready || ERROR_OPERATION_ABORTED == DErr) {
657     _endthread();
658     }
659     ClearCommError(cv->ComID,&DErr,NULL);
660     }
661     }
662     }
663    
664     void CommStart(PComVar cv, LONG lParam, PTTSet ts)
665     {
666     char ErrMsg[31];
667     char Temp[20];
668     char uimsg[MAX_UIMSG];
669    
670     if (! cv->Open ) {
671     return;
672     }
673     if ( cv->Ready ) {
674     return;
675     }
676    
677     // �L�����Z���^�C�}�����������������B�������A�������_�� WM_TIMER �����������������\���������B
678     if (*cv->ConnetingTimeout > 0) {
679     KillTimer(cv->HWin, IdCancelConnectTimer);
680     }
681    
682     switch (cv->PortType) {
683     case IdTCPIP:
684     ErrMsg[0] = 0;
685     switch (HIWORD(lParam)) {
686     case WSAECONNREFUSED:
687     get_lang_msg("MSG_COMM_REFUSE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection refused", ts->UILanguageFile);
688     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
689     break;
690     case WSAENETUNREACH:
691     get_lang_msg("MSG_COMM_REACH_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Network cannot be reached", ts->UILanguageFile);
692     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
693     break;
694     case WSAETIMEDOUT:
695     get_lang_msg("MSG_COMM_CONNECT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection timed out", ts->UILanguageFile);
696     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
697     break;
698     default:
699     get_lang_msg("MSG_COMM_TIMEOUT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot connect the host", ts->UILanguageFile);
700     _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
701     }
702     if (HIWORD(lParam)>0) {
703     /* connect() failed */
704     if (cv->res->ai_next != NULL) {
705     /* try to connect with other protocol */
706     CloseSocket(cv->s);
707     for (cv->res = cv->res->ai_next; cv->res; cv->res = cv->res->ai_next) {
708     cv->s = OpenSocket(cv);
709     if (cv->s == INVALID_SOCKET) {
710     CloseSocket(cv->s);
711     continue;
712     }
713     AsyncConnect(cv);
714     cv->Ready = FALSE;
715     cv->RetryWithOtherProtocol = TRUE; /* retry with other procotol */
716     return;
717     }
718     } else {
719     /* trying with all protocol family are failed */
720     if (cv->NoMsg==0)
721     {
722     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
723     MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
724     }
725     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
726     cv->RetryWithOtherProtocol = FALSE;
727     return;
728     }
729     }
730    
731     /* here is connection established */
732     cv->RetryWithOtherProtocol = FALSE;
733     PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_READ | FD_OOB | FD_CLOSE);
734     TCPIPClosed = FALSE;
735     break;
736    
737     case IdSerial:
738     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
739     ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp);
740     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort);
741     memset(&wol,0,sizeof(OVERLAPPED));
742     wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp);
743     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort);
744     memset(&rol,0,sizeof(OVERLAPPED));
745     rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp);
746    
747     /* create the receiver thread */
748     if (_beginthread(CommThread,0,cv) == -1) {
749     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
750     get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile);
751     MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
752     }
753     break;
754    
755     case IdFile:
756     cv->RRQ = TRUE;
757     break;
758 yutakapon 4857
759     case IdNamedPipe:
760     cv->ComPort = 0;
761     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
762     ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp);
763     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort);
764     memset(&wol,0,sizeof(OVERLAPPED));
765     wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp);
766     _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort);
767     memset(&rol,0,sizeof(OVERLAPPED));
768     rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp);
769    
770     /* create the receiver thread */
771     if (_beginthread(NamedPipeThread,0,cv) == -1) {
772     get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
773     get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile);
774     MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
775     }
776     break;
777 maya 3857 }
778     cv->Ready = TRUE;
779 doda 6947 cv->ConnectedTime = GetTickCount();
780 maya 3857 }
781    
782     BOOL CommCanClose(PComVar cv)
783     { // check if data remains in buffer
784     if (! cv->Open) {
785     return TRUE;
786     }
787     if (cv->InBuffCount>0) {
788     return FALSE;
789     }
790     if ((cv->HLogBuf!=NULL) &&
791     ((cv->LCount>0) ||
792     (cv->DCount>0))) {
793     return FALSE;
794     }
795     if ((cv->HBinBuf!=NULL) &&
796     (cv->BCount>0)) {
797     return FALSE;
798     }
799     return TRUE;
800     }
801    
802     void CommClose(PComVar cv)
803     {
804     if ( ! cv->Open ) {
805     return;
806     }
807     cv->Open = FALSE;
808    
809     /* disable event message posting & flush buffer */
810     cv->RRQ = FALSE;
811     cv->Ready = FALSE;
812     cv->InPtr = 0;
813     cv->InBuffCount = 0;
814     cv->OutPtr = 0;
815     cv->OutBuffCount = 0;
816     cv->LineModeBuffCount = 0;
817     cv->FlushLen = 0;
818     cv->Flush = FALSE;
819    
820     /* close port & release resources */
821     switch (cv->PortType) {
822     case IdTCPIP:
823     if (HAsync!=0) {
824     PWSACancelAsyncRequest(HAsync);
825     }
826     HAsync = 0;
827 doda 4165 Pfreeaddrinfo(cv->res0);
828 maya 3857 if ( cv->s!=INVALID_SOCKET ) {
829     Pclosesocket(cv->s);
830     }
831     cv->s = INVALID_SOCKET;
832     TTXCloseTCP(); /* TTPLUG */
833     FreeWinsock();
834     break;
835     case IdSerial:
836     if ( cv->ComID != INVALID_HANDLE_VALUE ) {
837     CloseHandle(ReadEnd);
838     CloseHandle(wol.hEvent);
839     CloseHandle(rol.hEvent);
840     PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT |
841     PURGE_TXCLEAR | PURGE_RXCLEAR);
842     EscapeCommFunction(cv->ComID,CLRDTR);
843     SetCommMask(cv->ComID,0);
844     PCloseFile(cv->ComID);
845     ClearCOMFlag(cv->ComPort);
846     }
847     TTXCloseFile(); /* TTPLUG */
848     break;
849     case IdFile:
850     if (cv->ComID != INVALID_HANDLE_VALUE) {
851     PCloseFile(cv->ComID);
852     }
853     TTXCloseFile(); /* TTPLUG */
854     break;
855 yutakapon 4857
856     case IdNamedPipe:
857     if ( cv->ComID != INVALID_HANDLE_VALUE ) {
858     CloseHandle(ReadEnd);
859     CloseHandle(wol.hEvent);
860     CloseHandle(rol.hEvent);
861     PCloseFile(cv->ComID);
862     }
863     TTXCloseFile(); /* TTPLUG */
864     break;
865 maya 3857 }
866     cv->ComID = INVALID_HANDLE_VALUE;
867     cv->PortType = 0;
868 doda 3932
869     _free_locale(cv->locale);
870 maya 3857 }
871    
872     void CommProcRRQ(PComVar cv)
873     {
874     if ( ! cv->Ready ) {
875     return;
876     }
877     /* disable receive request */
878     switch (cv->PortType) {
879     case IdTCPIP:
880     if (! TCPIPClosed) {
881     PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_OOB | FD_CLOSE);
882     }
883     break;
884     case IdSerial:
885     break;
886     }
887     cv->RRQ = TRUE;
888     CommReceive(cv);
889     }
890    
891     void CommReceive(PComVar cv)
892     {
893     DWORD C;
894     DWORD DErr;
895    
896     if (! cv->Ready || ! cv->RRQ ||
897     (cv->InBuffCount>=InBuffSize)) {
898     return;
899     }
900    
901     /* Compact buffer */
902     if ((cv->InBuffCount>0) && (cv->InPtr>0)) {
903     memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount);
904     cv->InPtr = 0;
905     }
906    
907     if (cv->InBuffCount<InBuffSize) {
908     switch (cv->PortType) {
909     case IdTCPIP:
910     C = Precv(cv->s, &(cv->InBuff[cv->InBuffCount]),
911     InBuffSize-cv->InBuffCount, 0);
912     if (C == SOCKET_ERROR) {
913     C = 0;
914     PWSAGetLastError();
915     }
916     cv->InBuffCount = cv->InBuffCount + C;
917     break;
918     case IdSerial:
919     do {
920     ClearCommError(cv->ComID,&DErr,NULL);
921     if (! PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),
922     InBuffSize-cv->InBuffCount,&C,&rol)) {
923     if (GetLastError() == ERROR_IO_PENDING) {
924     if (WaitForSingleObject(rol.hEvent, 1000) != WAIT_OBJECT_0) {
925     C = 0;
926     }
927     else {
928     GetOverlappedResult(cv->ComID,&rol,&C,FALSE);
929     }
930     }
931     else {
932     C = 0;
933     }
934     }
935     cv->InBuffCount = cv->InBuffCount + C;
936     } while ((C!=0) && (cv->InBuffCount<InBuffSize));
937     ClearCommError(cv->ComID,&DErr,NULL);
938     break;
939     case IdFile:
940     if (PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),
941     InBuffSize-cv->InBuffCount,&C,NULL)) {
942     if (C == 0) {
943     DErr = ERROR_HANDLE_EOF;
944     }
945     else {
946     cv->InBuffCount = cv->InBuffCount + C;
947     }
948     }
949     else {
950     DErr = GetLastError();
951     }
952     break;
953 yutakapon 4857
954     case IdNamedPipe:
955     // �L���[����������1�o�C�g�������f�[�^�������������������m�F���������������A
956     // ReadFile() ���u���b�N�������������������A�������������B
957     if (PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),
958     InBuffSize-cv->InBuffCount,&C,NULL)) {
959     if (C == 0) {
960     DErr = ERROR_HANDLE_EOF;
961     }
962     else {
963     cv->InBuffCount = cv->InBuffCount + C;
964     }
965     }
966     else {
967     DErr = GetLastError();
968     }
969    
970     // 1�o�C�g�������������A�C�x���g���N�����A�X���b�h�����J�������B
971     if (cv->InBuffCount > 0) {
972     cv->RRQ = FALSE;
973     SetEvent(ReadEnd);
974     }
975     break;
976 maya 3857 }
977     }
978    
979     if (cv->InBuffCount==0) {
980     switch (cv->PortType) {
981     case IdTCPIP:
982     if (! TCPIPClosed) {
983     PWSAAsyncSelect(cv->s,cv->HWin, WM_USER_COMMNOTIFY,
984     FD_READ | FD_OOB | FD_CLOSE);
985     }
986     break;
987     case IdSerial:
988     cv->RRQ = FALSE;
989     SetEvent(ReadEnd);
990     return;
991     case IdFile:
992     if (DErr != ERROR_IO_PENDING) {
993     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
994     cv->RRQ = FALSE;
995     }
996     else {
997     cv->RRQ = TRUE;
998     }
999     return;
1000 yutakapon 4857 case IdNamedPipe:
1001     // TODO: �������A���������������������B
1002     if (DErr != ERROR_IO_PENDING) {
1003     PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
1004     cv->RRQ = FALSE;
1005     }
1006     else {
1007     cv->RRQ = TRUE;
1008     }
1009     SetEvent(ReadEnd);
1010     return;
1011 maya 3857 }
1012     cv->RRQ = FALSE;
1013     }
1014     }
1015    
1016     void CommSend(PComVar cv)
1017     {
1018     int delay;
1019     COMSTAT Stat;
1020     BYTE LineEnd;
1021     int C, D, Max;
1022     DWORD DErr;
1023    
1024     if ((! cv->Open) || (! cv->Ready)) {
1025 doda 6435 cv->OutBuffCount = 0;
1026 maya 3857 return;
1027     }
1028    
1029     if ((cv->OutBuffCount == 0) || (! cv->CanSend)) {
1030     return;
1031     }
1032    
1033     /* Max num of bytes to be written */
1034     switch (cv->PortType) {
1035     case IdTCPIP:
1036     if (TCPIPClosed) {
1037     cv->OutBuffCount = 0;
1038     }
1039     Max = cv->OutBuffCount;
1040     break;
1041     case IdSerial:
1042     ClearCommError(cv->ComID,&DErr,&Stat);
1043     Max = OutBuffSize - Stat.cbOutQue;
1044     break;
1045     case IdFile:
1046     Max = cv->OutBuffCount;
1047     break;
1048 yutakapon 4857 case IdNamedPipe:
1049     Max = cv->OutBuffCount;
1050     break;
1051 maya 3857 }
1052    
1053     if ( Max<=0 ) {
1054     return;
1055     }
1056     if ( Max > cv->OutBuffCount ) {
1057     Max = cv->OutBuffCount;
1058     }
1059    
1060     if (cv->PortType == IdTCPIP && cv->TelFlag) {
1061     cv->LastSendTime = time(NULL);
1062     }
1063    
1064     C = Max;
1065     delay = 0;
1066    
1067     if ( cv->DelayFlag && (cv->PortType==IdSerial) ) {
1068     if ( cv->DelayPerLine > 0 ) {
1069     if ( cv->CRSend==IdCR ) {
1070     LineEnd = 0x0d;
1071     }
1072 maya 6479 else { // CRLF or LF
1073 maya 3857 LineEnd = 0x0a;
1074     }
1075     C = 1;
1076     if ( cv->DelayPerChar==0 ) {
1077     while ((C<Max) && (cv->OutBuff[cv->OutPtr+C-1]!=LineEnd)) {
1078     C++;
1079     }
1080     }
1081     if ( cv->OutBuff[cv->OutPtr+C-1]==LineEnd ) {
1082     delay = cv->DelayPerLine;
1083     }
1084     else {
1085     delay = cv->DelayPerChar;
1086     }
1087     }
1088     else if ( cv->DelayPerChar > 0 ) {
1089     C = 1;
1090     delay = cv->DelayPerChar;
1091     }
1092     }
1093    
1094     /* Write to comm driver/Winsock */
1095     switch (cv->PortType) {
1096     case IdTCPIP:
1097     D = Psend(cv->s, &(cv->OutBuff[cv->OutPtr]), C, 0);
1098     if ( D==SOCKET_ERROR ) { /* if error occurs */
1099     PWSAGetLastError(); /* Clear error */
1100     D = 0;
1101     }
1102     break;
1103    
1104     case IdSerial:
1105     if (! PWriteFile(cv->ComID,&(cv->OutBuff[cv->OutPtr]),C,(LPDWORD)&D,&wol)) {
1106     if (GetLastError() == ERROR_IO_PENDING) {
1107     if (WaitForSingleObject(wol.hEvent,1000) != WAIT_OBJECT_0) {
1108     D = C; /* Time out, ignore data */
1109     }
1110     else {
1111     GetOverlappedResult(cv->ComID,&wol,(LPDWORD)&D,FALSE);
1112     }
1113     }
1114     else { /* I/O error */
1115     D = C; /* ignore error */
1116     }
1117     }
1118     ClearCommError(cv->ComID,&DErr,&Stat);
1119     break;
1120    
1121     case IdFile:
1122     if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) {
1123     if (! GetLastError() == ERROR_IO_PENDING) {
1124     D = C; /* ignore data */
1125     }
1126     }
1127     break;
1128 yutakapon 4857
1129     case IdNamedPipe:
1130     if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) {
1131 yutakapon 4863 // ERROR_IO_PENDING ���O���G���[���������A�p�C�v���N���[�Y�������������������������A
1132     // ���M�����������������B
1133     if (! (GetLastError() == ERROR_IO_PENDING)) {
1134 yutakapon 4857 D = C; /* ignore data */
1135     }
1136     }
1137     break;
1138 maya 3857 }
1139    
1140     cv->OutBuffCount = cv->OutBuffCount - D;
1141     if ( cv->OutBuffCount==0 ) {
1142     cv->OutPtr = 0;
1143     }
1144     else {
1145     cv->OutPtr = cv->OutPtr + D;
1146     }
1147    
1148     if ( (C==D) && (delay>0) ) {
1149     cv->CanSend = FALSE;
1150     SetTimer(cv->HWin, IdDelayTimer, delay, NULL);
1151     }
1152     }
1153    
1154 maya 5694 void CommSendBreak(PComVar cv, int msec)
1155 maya 3857 /* for only serial ports */
1156     {
1157     MSG DummyMsg;
1158    
1159     if ( ! cv->Ready ) {
1160     return;
1161     }
1162    
1163     switch (cv->PortType) {
1164     case IdSerial:
1165     /* Set com port into a break state */
1166     SetCommBreak(cv->ComID);
1167    
1168     /* pause for 1 sec */
1169 maya 5694 if (SetTimer(cv->HWin, IdBreakTimer, msec, NULL) != 0) {
1170 maya 3857 GetMessage(&DummyMsg,cv->HWin,WM_TIMER,WM_TIMER);
1171     }
1172    
1173     /* Set com port into the nonbreak state */
1174     ClearCommBreak(cv->ComID);
1175     break;
1176     }
1177     }
1178    
1179     void CommLock(PTTSet ts, PComVar cv, BOOL Lock)
1180     {
1181     BYTE b;
1182     DWORD Func;
1183    
1184     if (! cv->Ready) {
1185     return;
1186     }
1187     if ((cv->PortType==IdTCPIP) ||
1188     (cv->PortType==IdSerial) &&
1189 yutakapon 8051 (!(ts->Flow == IdFlowHard || ts->Flow == IdFlowHardDsrDtr))
1190     ) {
1191 maya 3857 if (Lock) {
1192     b = XOFF;
1193     }
1194     else {
1195     b = XON;
1196     }
1197     CommBinaryOut(cv,&b,1);
1198     }
1199     else if ((cv->PortType==IdSerial) &&
1200 yutakapon 8051 (ts->Flow == IdFlowHard || ts->Flow == IdFlowHardDsrDtr)) {
1201     // �n�[�h�E�F�A�t���[���������������g���@�\�R�[�h�������������B
1202 maya 3857 if (Lock) {
1203     Func = CLRRTS;
1204 yutakapon 8051 if (ts->Flow == IdFlowHardDsrDtr)
1205     Func = CLRDTR;
1206 maya 3857 }
1207     else {
1208     Func = SETRTS;
1209 yutakapon 8051 if (ts->Flow == IdFlowHardDsrDtr)
1210     Func = SETDTR;
1211 maya 3857 }
1212     EscapeCommFunction(cv->ComID,Func);
1213     }
1214     }
1215    
1216     BOOL PrnOpen(PCHAR DevName)
1217     {
1218 maya 4283 char Temp[MAXPATHLEN], *c;
1219 maya 3857 DCB dcb;
1220     DWORD DErr;
1221     COMMTIMEOUTS ctmo;
1222    
1223     strncpy_s(Temp, sizeof(Temp),DevName, _TRUNCATE);
1224 maya 4283 c = Temp;
1225     while (*c != '\0' && *c != ':') {
1226     c++;
1227     }
1228     *c = '\0';
1229 maya 3857 LPTFlag = (Temp[0]=='L') ||
1230     (Temp[0]=='l');
1231 maya 4284
1232 yutakapon 6286 if (IsWindowsNTKernel()) {
1233 maya 4284 // �l�b�g���[�N���L���}�b�v�������f�o�C�X�������������A�������������������������� (2011.01.25 maya)
1234     // http://logmett.com/forum/viewtopic.php?f=2&t=1383
1235     // http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx#5
1236     PrnID = CreateFile(Temp,GENERIC_WRITE | FILE_READ_ATTRIBUTES,
1237     FILE_SHARE_READ,NULL,CREATE_ALWAYS,
1238     0,NULL);
1239     }
1240     else {
1241     // 9x �������L���R�[�h���������������������]������������
1242     PrnID = CreateFile(Temp,GENERIC_WRITE,
1243     0,NULL,OPEN_EXISTING,
1244     0,NULL);
1245     }
1246    
1247 maya 3857 if (PrnID == INVALID_HANDLE_VALUE) {
1248     return FALSE;
1249     }
1250    
1251     if (GetCommState(PrnID,&dcb)) {
1252     BuildCommDCB(DevName,&dcb);
1253     SetCommState(PrnID,&dcb);
1254     }
1255     ClearCommError(PrnID,&DErr,NULL);
1256     if (! LPTFlag) {
1257     SetupComm(PrnID,0,CommOutQueSize);
1258     }
1259     /* flush output buffer */
1260     PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR);
1261     memset(&ctmo,0,sizeof(ctmo));
1262     ctmo.WriteTotalTimeoutConstant = 1000;
1263     SetCommTimeouts(PrnID,&ctmo);
1264     if (! LPTFlag) {
1265     EscapeCommFunction(PrnID,SETDTR);
1266     }
1267     return TRUE;
1268     }
1269    
1270     int PrnWrite(PCHAR b, int c)
1271     {
1272     int d;
1273     DWORD DErr;
1274     COMSTAT Stat;
1275    
1276     if (PrnID == INVALID_HANDLE_VALUE ) {
1277     return c;
1278     }
1279    
1280     ClearCommError(PrnID,&DErr,&Stat);
1281     if (! LPTFlag &&
1282     (OutBuffSize - (int)Stat.cbOutQue < c)) {
1283     c = OutBuffSize - Stat.cbOutQue;
1284     }
1285     if (c<=0) {
1286     return 0;
1287     }
1288     if (! WriteFile(PrnID,b,c,(LPDWORD)&d,NULL)) {
1289     d = 0;
1290     }
1291     ClearCommError(PrnID,&DErr,NULL);
1292     return d;
1293     }
1294    
1295     void PrnCancel()
1296     {
1297     PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR);
1298     PrnClose();
1299     }
1300    
1301     void PrnClose()
1302     {
1303     if (PrnID != INVALID_HANDLE_VALUE) {
1304     if (!LPTFlag) {
1305     EscapeCommFunction(PrnID,CLRDTR);
1306     }
1307     CloseHandle(PrnID);
1308     }
1309     PrnID = INVALID_HANDLE_VALUE;
1310     }

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