Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ttcomtester/teraterm/teraterm/commlib.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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