Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6662 - (show annotations) (download) (as text)
Mon Apr 3 12:51:37 2017 UTC (7 years 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 /* 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 #endif /* NO_INET6 */
23 #include <stdio.h> /* for _snprintf() */
24 #include <time.h>
25 #include <locale.h>
26
27 #ifndef NO_INET6
28 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 #endif /* NO_INET6 */
78
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
129 cv->NotifyIcon = NULL;
130 }
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 dcb.BaudRate = ts->Baud;
167 dcb.fBinary = TRUE;
168 switch (ts->Parity) {
169 case IdParityNone:
170 dcb.Parity = NOPARITY;
171 break;
172 case IdParityOdd:
173 dcb.fParity = TRUE;
174 dcb.Parity = ODDPARITY;
175 break;
176 case IdParityEven:
177 dcb.fParity = TRUE;
178 dcb.Parity = EVENPARITY;
179 break;
180 case IdParityMark:
181 dcb.fParity = TRUE;
182 dcb.Parity = MARKPARITY;
183 break;
184 case IdParitySpace:
185 dcb.fParity = TRUE;
186 dcb.Parity = SPACEPARITY;
187 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 case IdStopBit15:
220 dcb.StopBits = ONE5STOPBITS;
221 break;
222 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 // ���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 void CommOpen(HWND HW, PTTSet ts, PComVar cv)
260 {
261 #ifdef NO_INET6
262 int Err;
263 #endif /* NO_INET6 */
264 char ErrMsg[21+256];
265 char P[50+256];
266
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 // �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 /* 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 cv->locale = _create_locale(LC_ALL, cv->Locale);
337 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 HAsync = PWSAAsyncGetAddrInfo(HW, WM_USER_GETHOST,
377 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 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 }
496 else {
497 cv->s= Psocket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
498 if (cv->s==INVALID_SOCKET)
499 {
500 InvalidHost = TRUE;
501 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 }
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
588 case IdNamedPipe:
589 InitFileIO(IdNamedPipe); /* TTPLUG */
590 TTXOpenFile(); /* TTPLUG */
591
592 memset(P, 0, sizeof(P));
593 strncpy_s(P, sizeof(P), ts->HostName, _TRUNCATE);
594
595 // ���O�t���p�C�v�����������������`�F�b�N�����B
596 if (CheckNamedPipeFormat(P, strlen(P)) < 0) {
597 InvalidHost = TRUE;
598
599 _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE,
600 "Invalid pipe name (%d)\n\n"
601 "A valid pipe name has the form\n"
602 "\"\\\\<ServerName>\\pipe\\<PipeName>\"",
603 GetLastError());
604 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 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 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
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 } /* 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 cv->s = INVALID_SOCKET; /* �\�P�b�g�����������t�����B(2010.8.6 yutaka) */
642 }
643 FreeWinsock();
644 }
645 return;
646 }
647 }
648
649 // ���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 DErr = GetLastError();
681 // [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 PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
685 _endthread();
686 }
687 }
688 }
689 }
690
691 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 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 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
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 }
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 Pfreeaddrinfo(cv->res0);
896 #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
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 }
935 cv->ComID = INVALID_HANDLE_VALUE;
936 cv->PortType = 0;
937
938 _free_locale(cv->locale);
939 }
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
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 }
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 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 }
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 cv->OutBuffCount = 0;
1095 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 case IdNamedPipe:
1118 Max = cv->OutBuffCount;
1119 break;
1120 }
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 else { // CRLF or LF
1142 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
1198 case IdNamedPipe:
1199 if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) {
1200 // ERROR_IO_PENDING ���O���G���[���������A�p�C�v���N���[�Y�������������������������A
1201 // ���M�����������������B
1202 if (! (GetLastError() == ERROR_IO_PENDING)) {
1203 D = C; /* ignore data */
1204 }
1205 }
1206 break;
1207 }
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 void CommSendBreak(PComVar cv, int msec)
1224 /* 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 if (SetTimer(cv->HWin, IdBreakTimer, msec, NULL) != 0) {
1239 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 char Temp[MAXPATHLEN], *c;
1282 DCB dcb;
1283 DWORD DErr;
1284 COMMTIMEOUTS ctmo;
1285
1286 strncpy_s(Temp, sizeof(Temp),DevName, _TRUNCATE);
1287 c = Temp;
1288 while (*c != '\0' && *c != ':') {
1289 c++;
1290 }
1291 *c = '\0';
1292 LPTFlag = (Temp[0]=='L') ||
1293 (Temp[0]=='l');
1294
1295 if (IsWindowsNTKernel()) {
1296 // �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 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