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 6662 - (hide annotations) (download) (as text)
Mon Apr 3 12:51:37 2017 UTC (6 years, 11 months ago) by doda
Original Path: trunk/teraterm/teraterm/commlib.c
File MIME type: text/x-csrc
File size: 36183 byte(s)
バルーン通知する為の関数を追加

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

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