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

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