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 6895 - (show annotations) (download) (as text)
Wed Aug 9 13:22:24 2017 UTC (6 years, 8 months ago) by doda
Original Path: trunk/teraterm/teraterm/commlib.c
File MIME type: text/x-csrc
File size: 35310 byte(s)
パイプが使用中の場合のメッセージを追加。

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

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