Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/commlib.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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