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

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