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 10587 - (show annotations) (download) (as text)
Mon Feb 6 13:26:12 2023 UTC (13 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 36344 byte(s)
シリアルのハードフローが動作しない対策,ラインチェック

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

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