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 4860 - (show annotations) (download) (as text)
Sat Mar 10 10:32:33 2012 UTC (12 years ago) by yutakapon
Original Path: trunk/teraterm/teraterm/commlib.c
File MIME type: text/x-csrc
File size: 35948 byte(s)
* Tera Term起動時、名前付きパイプはTCP/IP扱いとした。
* TCP/IPのホスト名で名前付きパイプを指定できるようにした。



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(); // this returns 995 (operation aborted) if a USB com port is removed
679 if (! cv->Ready || ERROR_OPERATION_ABORTED == DErr) {
680 _endthread();
681 }
682 }
683 }
684 }
685
686 void CommThread(void *arg)
687 {
688 DWORD Evt;
689 PComVar cv = (PComVar)arg;
690 DWORD DErr;
691 HANDLE REnd;
692 char Temp[20];
693
694 _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
695 REnd = OpenEvent(EVENT_ALL_ACCESS,FALSE, Temp);
696 while (TRUE) {
697 if (WaitCommEvent(cv->ComID,&Evt,NULL)) {
698 if (! cv->Ready) {
699 _endthread();
700 }
701 if (! cv->RRQ) {
702 PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_READ);
703 }
704 WaitForSingleObject(REnd,INFINITE);
705 }
706 else {
707 DErr = GetLastError(); // this returns 995 (operation aborted) if a USB com port is removed
708 if (! cv->Ready || ERROR_OPERATION_ABORTED == DErr) {
709 _endthread();
710 }
711 ClearCommError(cv->ComID,&DErr,NULL);
712 }
713 }
714 }
715
716 void CommStart(PComVar cv, LONG lParam, PTTSet ts)
717 {
718 char ErrMsg[31];
719 char Temp[20];
720 char uimsg[MAX_UIMSG];
721
722 if (! cv->Open ) {
723 return;
724 }
725 if ( cv->Ready ) {
726 return;
727 }
728
729 // �L�����Z���^�C�}�����������������B�������A�������_�� WM_TIMER �����������������\���������B
730 if (*cv->ConnetingTimeout > 0) {
731 KillTimer(cv->HWin, IdCancelConnectTimer);
732 }
733
734 switch (cv->PortType) {
735 case IdTCPIP:
736 ErrMsg[0] = 0;
737 switch (HIWORD(lParam)) {
738 case WSAECONNREFUSED:
739 get_lang_msg("MSG_COMM_REFUSE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection refused", ts->UILanguageFile);
740 _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
741 break;
742 case WSAENETUNREACH:
743 get_lang_msg("MSG_COMM_REACH_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Network cannot be reached", ts->UILanguageFile);
744 _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
745 break;
746 case WSAETIMEDOUT:
747 get_lang_msg("MSG_COMM_CONNECT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection timed out", ts->UILanguageFile);
748 _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
749 break;
750 default:
751 get_lang_msg("MSG_COMM_TIMEOUT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot connect the host", ts->UILanguageFile);
752 _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg);
753 }
754 if (HIWORD(lParam)>0) {
755 #ifndef NO_INET6
756 /* connect() failed */
757 if (cv->res->ai_next != NULL) {
758 /* try to connect with other protocol */
759 CloseSocket(cv->s);
760 for (cv->res = cv->res->ai_next; cv->res; cv->res = cv->res->ai_next) {
761 cv->s = OpenSocket(cv);
762 if (cv->s == INVALID_SOCKET) {
763 CloseSocket(cv->s);
764 continue;
765 }
766 AsyncConnect(cv);
767 cv->Ready = FALSE;
768 cv->RetryWithOtherProtocol = TRUE; /* retry with other procotol */
769 return;
770 }
771 } else {
772 /* trying with all protocol family are failed */
773 if (cv->NoMsg==0)
774 {
775 get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
776 MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
777 }
778 PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
779 cv->RetryWithOtherProtocol = FALSE;
780 return;
781 }
782 #else
783 if (cv->NoMsg==0) {
784 get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
785 MessageBox(cv->HWin, ErrMsg, uimsg, MB_TASKMODAL | MB_ICONEXCLAMATION);
786 }
787 PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
788 return;
789 #endif /* NO_INET6 */
790 }
791
792 #ifndef NO_INET6
793 /* here is connection established */
794 cv->RetryWithOtherProtocol = FALSE;
795 #endif /* NO_INET6 */
796 PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_READ | FD_OOB | FD_CLOSE);
797 TCPIPClosed = FALSE;
798 break;
799
800 case IdSerial:
801 _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
802 ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp);
803 _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort);
804 memset(&wol,0,sizeof(OVERLAPPED));
805 wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp);
806 _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort);
807 memset(&rol,0,sizeof(OVERLAPPED));
808 rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp);
809
810 /* create the receiver thread */
811 if (_beginthread(CommThread,0,cv) == -1) {
812 get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
813 get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile);
814 MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
815 }
816 break;
817
818 case IdFile:
819 cv->RRQ = TRUE;
820 break;
821
822 case IdNamedPipe:
823 cv->ComPort = 0;
824 _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort);
825 ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp);
826 _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort);
827 memset(&wol,0,sizeof(OVERLAPPED));
828 wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp);
829 _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort);
830 memset(&rol,0,sizeof(OVERLAPPED));
831 rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp);
832
833 /* create the receiver thread */
834 if (_beginthread(NamedPipeThread,0,cv) == -1) {
835 get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile);
836 get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile);
837 MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION);
838 }
839 break;
840 }
841 cv->Ready = TRUE;
842 }
843
844 BOOL CommCanClose(PComVar cv)
845 { // check if data remains in buffer
846 if (! cv->Open) {
847 return TRUE;
848 }
849 if (cv->InBuffCount>0) {
850 return FALSE;
851 }
852 if ((cv->HLogBuf!=NULL) &&
853 ((cv->LCount>0) ||
854 (cv->DCount>0))) {
855 return FALSE;
856 }
857 if ((cv->HBinBuf!=NULL) &&
858 (cv->BCount>0)) {
859 return FALSE;
860 }
861 return TRUE;
862 }
863
864 void CommClose(PComVar cv)
865 {
866 if ( ! cv->Open ) {
867 return;
868 }
869 cv->Open = FALSE;
870
871 /* disable event message posting & flush buffer */
872 cv->RRQ = FALSE;
873 cv->Ready = FALSE;
874 cv->InPtr = 0;
875 cv->InBuffCount = 0;
876 cv->OutPtr = 0;
877 cv->OutBuffCount = 0;
878 cv->LineModeBuffCount = 0;
879 cv->FlushLen = 0;
880 cv->Flush = FALSE;
881
882 /* close port & release resources */
883 switch (cv->PortType) {
884 case IdTCPIP:
885 if (HAsync!=0) {
886 PWSACancelAsyncRequest(HAsync);
887 }
888 HAsync = 0;
889 #ifndef NO_INET6
890 Pfreeaddrinfo(cv->res0);
891 #endif /* NO_INET6 */
892 if ( cv->s!=INVALID_SOCKET ) {
893 Pclosesocket(cv->s);
894 }
895 cv->s = INVALID_SOCKET;
896 TTXCloseTCP(); /* TTPLUG */
897 FreeWinsock();
898 break;
899 case IdSerial:
900 if ( cv->ComID != INVALID_HANDLE_VALUE ) {
901 CloseHandle(ReadEnd);
902 CloseHandle(wol.hEvent);
903 CloseHandle(rol.hEvent);
904 PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT |
905 PURGE_TXCLEAR | PURGE_RXCLEAR);
906 EscapeCommFunction(cv->ComID,CLRDTR);
907 SetCommMask(cv->ComID,0);
908 PCloseFile(cv->ComID);
909 ClearCOMFlag(cv->ComPort);
910 }
911 TTXCloseFile(); /* TTPLUG */
912 break;
913 case IdFile:
914 if (cv->ComID != INVALID_HANDLE_VALUE) {
915 PCloseFile(cv->ComID);
916 }
917 TTXCloseFile(); /* TTPLUG */
918 break;
919
920 case IdNamedPipe:
921 if ( cv->ComID != INVALID_HANDLE_VALUE ) {
922 CloseHandle(ReadEnd);
923 CloseHandle(wol.hEvent);
924 CloseHandle(rol.hEvent);
925 PCloseFile(cv->ComID);
926 }
927 TTXCloseFile(); /* TTPLUG */
928 break;
929 }
930 cv->ComID = INVALID_HANDLE_VALUE;
931 cv->PortType = 0;
932
933 _free_locale(cv->locale);
934 }
935
936 void CommProcRRQ(PComVar cv)
937 {
938 if ( ! cv->Ready ) {
939 return;
940 }
941 /* disable receive request */
942 switch (cv->PortType) {
943 case IdTCPIP:
944 if (! TCPIPClosed) {
945 PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_OOB | FD_CLOSE);
946 }
947 break;
948 case IdSerial:
949 break;
950 }
951 cv->RRQ = TRUE;
952 CommReceive(cv);
953 }
954
955 void CommReceive(PComVar cv)
956 {
957 DWORD C;
958 DWORD DErr;
959
960 if (! cv->Ready || ! cv->RRQ ||
961 (cv->InBuffCount>=InBuffSize)) {
962 return;
963 }
964
965 /* Compact buffer */
966 if ((cv->InBuffCount>0) && (cv->InPtr>0)) {
967 memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount);
968 cv->InPtr = 0;
969 }
970
971 if (cv->InBuffCount<InBuffSize) {
972 switch (cv->PortType) {
973 case IdTCPIP:
974 C = Precv(cv->s, &(cv->InBuff[cv->InBuffCount]),
975 InBuffSize-cv->InBuffCount, 0);
976 if (C == SOCKET_ERROR) {
977 C = 0;
978 PWSAGetLastError();
979 }
980 cv->InBuffCount = cv->InBuffCount + C;
981 break;
982 case IdSerial:
983 do {
984 ClearCommError(cv->ComID,&DErr,NULL);
985 if (! PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),
986 InBuffSize-cv->InBuffCount,&C,&rol)) {
987 if (GetLastError() == ERROR_IO_PENDING) {
988 if (WaitForSingleObject(rol.hEvent, 1000) != WAIT_OBJECT_0) {
989 C = 0;
990 }
991 else {
992 GetOverlappedResult(cv->ComID,&rol,&C,FALSE);
993 }
994 }
995 else {
996 C = 0;
997 }
998 }
999 cv->InBuffCount = cv->InBuffCount + C;
1000 } while ((C!=0) && (cv->InBuffCount<InBuffSize));
1001 ClearCommError(cv->ComID,&DErr,NULL);
1002 break;
1003 case IdFile:
1004 if (PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),
1005 InBuffSize-cv->InBuffCount,&C,NULL)) {
1006 if (C == 0) {
1007 DErr = ERROR_HANDLE_EOF;
1008 }
1009 else {
1010 cv->InBuffCount = cv->InBuffCount + C;
1011 }
1012 }
1013 else {
1014 DErr = GetLastError();
1015 }
1016 break;
1017
1018 case IdNamedPipe:
1019 // �L���[����������1�o�C�g�������f�[�^�������������������m�F���������������A
1020 // ReadFile() ���u���b�N�������������������A�������������B
1021 if (PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]),
1022 InBuffSize-cv->InBuffCount,&C,NULL)) {
1023 if (C == 0) {
1024 DErr = ERROR_HANDLE_EOF;
1025 }
1026 else {
1027 cv->InBuffCount = cv->InBuffCount + C;
1028 }
1029 }
1030 else {
1031 DErr = GetLastError();
1032 }
1033
1034 // 1�o�C�g�������������A�C�x���g���N�����A�X���b�h�����J�������B
1035 if (cv->InBuffCount > 0) {
1036 cv->RRQ = FALSE;
1037 SetEvent(ReadEnd);
1038 }
1039 break;
1040 }
1041 }
1042
1043 if (cv->InBuffCount==0) {
1044 switch (cv->PortType) {
1045 case IdTCPIP:
1046 if (! TCPIPClosed) {
1047 PWSAAsyncSelect(cv->s,cv->HWin, WM_USER_COMMNOTIFY,
1048 FD_READ | FD_OOB | FD_CLOSE);
1049 }
1050 break;
1051 case IdSerial:
1052 cv->RRQ = FALSE;
1053 SetEvent(ReadEnd);
1054 return;
1055 case IdFile:
1056 if (DErr != ERROR_IO_PENDING) {
1057 PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
1058 cv->RRQ = FALSE;
1059 }
1060 else {
1061 cv->RRQ = TRUE;
1062 }
1063 return;
1064 case IdNamedPipe:
1065 // TODO: �������A���������������������B
1066 if (DErr != ERROR_IO_PENDING) {
1067 PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE);
1068 cv->RRQ = FALSE;
1069 }
1070 else {
1071 cv->RRQ = TRUE;
1072 }
1073 SetEvent(ReadEnd);
1074 return;
1075 }
1076 cv->RRQ = FALSE;
1077 }
1078 }
1079
1080 void CommSend(PComVar cv)
1081 {
1082 int delay;
1083 COMSTAT Stat;
1084 BYTE LineEnd;
1085 int C, D, Max;
1086 DWORD DErr;
1087
1088 if ((! cv->Open) || (! cv->Ready)) {
1089 cv->OutBuffCount = 0;
1090 return;
1091 }
1092
1093 if ((cv->OutBuffCount == 0) || (! cv->CanSend)) {
1094 return;
1095 }
1096
1097 /* Max num of bytes to be written */
1098 switch (cv->PortType) {
1099 case IdTCPIP:
1100 if (TCPIPClosed) {
1101 cv->OutBuffCount = 0;
1102 }
1103 Max = cv->OutBuffCount;
1104 break;
1105 case IdSerial:
1106 ClearCommError(cv->ComID,&DErr,&Stat);
1107 Max = OutBuffSize - Stat.cbOutQue;
1108 break;
1109 case IdFile:
1110 Max = cv->OutBuffCount;
1111 break;
1112 case IdNamedPipe:
1113 Max = cv->OutBuffCount;
1114 break;
1115 }
1116
1117 if ( Max<=0 ) {
1118 return;
1119 }
1120 if ( Max > cv->OutBuffCount ) {
1121 Max = cv->OutBuffCount;
1122 }
1123
1124 if (cv->PortType == IdTCPIP && cv->TelFlag) {
1125 cv->LastSendTime = time(NULL);
1126 }
1127
1128 C = Max;
1129 delay = 0;
1130
1131 if ( cv->DelayFlag && (cv->PortType==IdSerial) ) {
1132 if ( cv->DelayPerLine > 0 ) {
1133 if ( cv->CRSend==IdCR ) {
1134 LineEnd = 0x0d;
1135 }
1136 else {
1137 LineEnd = 0x0a;
1138 }
1139 C = 1;
1140 if ( cv->DelayPerChar==0 ) {
1141 while ((C<Max) && (cv->OutBuff[cv->OutPtr+C-1]!=LineEnd)) {
1142 C++;
1143 }
1144 }
1145 if ( cv->OutBuff[cv->OutPtr+C-1]==LineEnd ) {
1146 delay = cv->DelayPerLine;
1147 }
1148 else {
1149 delay = cv->DelayPerChar;
1150 }
1151 }
1152 else if ( cv->DelayPerChar > 0 ) {
1153 C = 1;
1154 delay = cv->DelayPerChar;
1155 }
1156 }
1157
1158 /* Write to comm driver/Winsock */
1159 switch (cv->PortType) {
1160 case IdTCPIP:
1161 D = Psend(cv->s, &(cv->OutBuff[cv->OutPtr]), C, 0);
1162 if ( D==SOCKET_ERROR ) { /* if error occurs */
1163 PWSAGetLastError(); /* Clear error */
1164 D = 0;
1165 }
1166 break;
1167
1168 case IdSerial:
1169 if (! PWriteFile(cv->ComID,&(cv->OutBuff[cv->OutPtr]),C,(LPDWORD)&D,&wol)) {
1170 if (GetLastError() == ERROR_IO_PENDING) {
1171 if (WaitForSingleObject(wol.hEvent,1000) != WAIT_OBJECT_0) {
1172 D = C; /* Time out, ignore data */
1173 }
1174 else {
1175 GetOverlappedResult(cv->ComID,&wol,(LPDWORD)&D,FALSE);
1176 }
1177 }
1178 else { /* I/O error */
1179 D = C; /* ignore error */
1180 }
1181 }
1182 ClearCommError(cv->ComID,&DErr,&Stat);
1183 break;
1184
1185 case IdFile:
1186 if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) {
1187 if (! GetLastError() == ERROR_IO_PENDING) {
1188 D = C; /* ignore data */
1189 }
1190 }
1191 break;
1192
1193 case IdNamedPipe:
1194 if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) {
1195 if (! GetLastError() == ERROR_IO_PENDING) {
1196 D = C; /* ignore data */
1197 }
1198 }
1199 break;
1200 }
1201
1202 cv->OutBuffCount = cv->OutBuffCount - D;
1203 if ( cv->OutBuffCount==0 ) {
1204 cv->OutPtr = 0;
1205 }
1206 else {
1207 cv->OutPtr = cv->OutPtr + D;
1208 }
1209
1210 if ( (C==D) && (delay>0) ) {
1211 cv->CanSend = FALSE;
1212 SetTimer(cv->HWin, IdDelayTimer, delay, NULL);
1213 }
1214 }
1215
1216 void CommSendBreak(PComVar cv)
1217 /* for only serial ports */
1218 {
1219 MSG DummyMsg;
1220
1221 if ( ! cv->Ready ) {
1222 return;
1223 }
1224
1225 switch (cv->PortType) {
1226 case IdSerial:
1227 /* Set com port into a break state */
1228 SetCommBreak(cv->ComID);
1229
1230 /* pause for 1 sec */
1231 if (SetTimer(cv->HWin, IdBreakTimer, 1000, NULL) != 0) {
1232 GetMessage(&DummyMsg,cv->HWin,WM_TIMER,WM_TIMER);
1233 }
1234
1235 /* Set com port into the nonbreak state */
1236 ClearCommBreak(cv->ComID);
1237 break;
1238 }
1239 }
1240
1241 void CommLock(PTTSet ts, PComVar cv, BOOL Lock)
1242 {
1243 BYTE b;
1244 DWORD Func;
1245
1246 if (! cv->Ready) {
1247 return;
1248 }
1249 if ((cv->PortType==IdTCPIP) ||
1250 (cv->PortType==IdSerial) &&
1251 (ts->Flow!=IdFlowHard)) {
1252 if (Lock) {
1253 b = XOFF;
1254 }
1255 else {
1256 b = XON;
1257 }
1258 CommBinaryOut(cv,&b,1);
1259 }
1260 else if ((cv->PortType==IdSerial) &&
1261 (ts->Flow==IdFlowHard)) {
1262 if (Lock) {
1263 Func = CLRRTS;
1264 }
1265 else {
1266 Func = SETRTS;
1267 }
1268 EscapeCommFunction(cv->ComID,Func);
1269 }
1270 }
1271
1272 BOOL PrnOpen(PCHAR DevName)
1273 {
1274 char Temp[MAXPATHLEN], *c;
1275 DCB dcb;
1276 DWORD DErr;
1277 COMMTIMEOUTS ctmo;
1278 OSVERSIONINFO osvi;
1279
1280 strncpy_s(Temp, sizeof(Temp),DevName, _TRUNCATE);
1281 c = Temp;
1282 while (*c != '\0' && *c != ':') {
1283 c++;
1284 }
1285 *c = '\0';
1286 LPTFlag = (Temp[0]=='L') ||
1287 (Temp[0]=='l');
1288
1289 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1290 GetVersionEx(&osvi);
1291 if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
1292 // �l�b�g���[�N���L���}�b�v�������f�o�C�X�������������A�������������������������� (2011.01.25 maya)
1293 // http://logmett.com/forum/viewtopic.php?f=2&t=1383
1294 // http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx#5
1295 PrnID = CreateFile(Temp,GENERIC_WRITE | FILE_READ_ATTRIBUTES,
1296 FILE_SHARE_READ,NULL,CREATE_ALWAYS,
1297 0,NULL);
1298 }
1299 else {
1300 // 9x �������L���R�[�h���������������������]������������
1301 PrnID = CreateFile(Temp,GENERIC_WRITE,
1302 0,NULL,OPEN_EXISTING,
1303 0,NULL);
1304 }
1305
1306 if (PrnID == INVALID_HANDLE_VALUE) {
1307 return FALSE;
1308 }
1309
1310 if (GetCommState(PrnID,&dcb)) {
1311 BuildCommDCB(DevName,&dcb);
1312 SetCommState(PrnID,&dcb);
1313 }
1314 ClearCommError(PrnID,&DErr,NULL);
1315 if (! LPTFlag) {
1316 SetupComm(PrnID,0,CommOutQueSize);
1317 }
1318 /* flush output buffer */
1319 PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR);
1320 memset(&ctmo,0,sizeof(ctmo));
1321 ctmo.WriteTotalTimeoutConstant = 1000;
1322 SetCommTimeouts(PrnID,&ctmo);
1323 if (! LPTFlag) {
1324 EscapeCommFunction(PrnID,SETDTR);
1325 }
1326 return TRUE;
1327 }
1328
1329 int PrnWrite(PCHAR b, int c)
1330 {
1331 int d;
1332 DWORD DErr;
1333 COMSTAT Stat;
1334
1335 if (PrnID == INVALID_HANDLE_VALUE ) {
1336 return c;
1337 }
1338
1339 ClearCommError(PrnID,&DErr,&Stat);
1340 if (! LPTFlag &&
1341 (OutBuffSize - (int)Stat.cbOutQue < c)) {
1342 c = OutBuffSize - Stat.cbOutQue;
1343 }
1344 if (c<=0) {
1345 return 0;
1346 }
1347 if (! WriteFile(PrnID,b,c,(LPDWORD)&d,NULL)) {
1348 d = 0;
1349 }
1350 ClearCommError(PrnID,&DErr,NULL);
1351 return d;
1352 }
1353
1354 void PrnCancel()
1355 {
1356 PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR);
1357 PrnClose();
1358 }
1359
1360 void PrnClose()
1361 {
1362 if (PrnID != INVALID_HANDLE_VALUE) {
1363 if (!LPTFlag) {
1364 EscapeCommFunction(PrnID,CLRDTR);
1365 }
1366 CloseHandle(PrnID);
1367 }
1368 PrnID = INVALID_HANDLE_VALUE;
1369 }

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