Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/commlib.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9206 - (hide annotations) (download) (as text)
Mon Apr 12 14:16:18 2021 UTC (2 years, 10 months ago) by nmaya
File MIME type: text/x-csrc
File size: 35786 byte(s)
シリアルポート接続の1.5ストップビットのサポートを削除

ticket #40299
1.5ストップビットは常に不正な設定となるため

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

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