Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8616 - (show annotations) (download) (as text)
Mon Mar 23 15:54:26 2020 UTC (3 years, 11 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 36231 byte(s)
TTMessageBoxW() を追加、一部利用するよう修正

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

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