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 4863 - (show annotations) (download) (as text)
Sun Mar 11 12:01:10 2012 UTC (12 years, 1 month ago) by yutakapon
Original Path: trunk/teraterm/teraterm/commlib.c
File MIME type: text/x-csrc
File size: 36119 byte(s)
一度確立した名前付きパイプが、切断された場合に対する考慮が漏れていたので、処理を追加した。
  - スレッドの終了エラーコードの修正およびFD_CLOSE処理
  - 送信処理のエラーチェックバグ修正

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

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