Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/filesys.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2635 - (hide annotations) (download) (as text)
Wed Jan 21 04:12:28 2009 UTC (15 years, 2 months ago) by maya
Original Path: teraterm/trunk/teraterm/filesys.cpp
File MIME type: text/x-c++src
File size: 28383 byte(s)
LogStart 関数が、ログファイルを開けたかどうかを返すようにした。

1 maya 2476 /* Tera Term
2     Copyright(C) 1994-1998 T. Teranishi
3     All rights reserved. */
4    
5     /* TERATERM.EXE, file transfer routines */
6     #include "stdafx.h"
7     #include "teraterm.h"
8     #include "tttypes.h"
9     #include "ttftypes.h"
10     #include "tt_res.h"
11     #include "ftdlg.h"
12     #include "protodlg.h"
13     #include "ttwinman.h"
14     #include "commlib.h"
15     #include "ttcommon.h"
16     #include "ttdde.h"
17     #include "ttlib.h"
18     #include "helpid.h"
19 doda 2576 #include "dlglib.h"
20 maya 2476
21     #include "filesys.h"
22     #include "ftlib.h"
23    
24     PFileVar LogVar = NULL;
25     PFileVar SendVar = NULL;
26     PFileVar FileVar = NULL;
27     static PCHAR ProtoVar = NULL;
28     static int ProtoId;
29    
30     static BYTE LogLast = 0;
31     BOOL FileLog = FALSE;
32     BOOL BinLog = FALSE;
33     BOOL DDELog = FALSE;
34     static BOOL FileRetrySend, FileRetryEcho, FileCRSend;
35     static BYTE FileByte;
36    
37     static BOOL FSend = FALSE;
38    
39     HWND HWndLog = NULL; //steven add
40    
41     static HMODULE HTTFILE = NULL;
42     static int TTFILECount = 0;
43    
44     PGetSetupFname GetSetupFname;
45     PGetTransFname GetTransFname;
46     PGetMultiFname GetMultiFname;
47     PGetGetFname GetGetFname;
48     PSetFileVar SetFileVar;
49     PGetXFname GetXFname;
50     PProtoInit ProtoInit;
51     PProtoParse ProtoParse;
52     PProtoTimeOutProc ProtoTimeOutProc;
53     PProtoCancel ProtoCancel;
54    
55     #define IdGetSetupFname 1
56     #define IdGetTransFname 2
57     #define IdGetMultiFname 3
58     #define IdGetGetFname 4
59     #define IdSetFileVar 5
60     #define IdGetXFname 6
61    
62     #define IdProtoInit 7
63     #define IdProtoParse 8
64     #define IdProtoTimeOutProc 9
65     #define IdProtoCancel 10
66    
67     /*
68     Line Head flag for timestamping
69     2007.05.24 Gentaro
70     */
71     enum enumLineEnd {
72     Line_Other = 0,
73     Line_LineHead = 1,
74     Line_FileHead = 2,
75     };
76    
77     enum enumLineEnd eLineEnd = Line_LineHead;
78    
79     BOOL LoadTTFILE()
80     {
81     BOOL Err;
82    
83     if (HTTFILE != NULL)
84     {
85     TTFILECount++;
86     return TRUE;
87     }
88     else
89     TTFILECount = 0;
90    
91     HTTFILE = LoadLibrary("TTPFILE.DLL");
92     if (HTTFILE == NULL)
93     return FALSE;
94    
95     TTFILESetUILanguageFile(ts.UILanguageFile);
96     TTFILESetFileSendFilter(ts.FileSendFilter);
97    
98     Err = FALSE;
99     GetSetupFname = (PGetSetupFname)GetProcAddress(HTTFILE,
100     MAKEINTRESOURCE(IdGetSetupFname));
101     if (GetSetupFname==NULL)
102     Err = TRUE;
103    
104     GetTransFname = (PGetTransFname)GetProcAddress(HTTFILE,
105     MAKEINTRESOURCE(IdGetTransFname));
106     if (GetTransFname==NULL)
107     Err = TRUE;
108    
109     GetMultiFname = (PGetMultiFname)GetProcAddress(HTTFILE,
110     MAKEINTRESOURCE(IdGetMultiFname));
111     if (GetMultiFname==NULL)
112     Err = TRUE;
113    
114     GetGetFname = (PGetGetFname)GetProcAddress(HTTFILE,
115     MAKEINTRESOURCE(IdGetGetFname));
116     if (GetGetFname==NULL)
117     Err = TRUE;
118    
119     SetFileVar = (PSetFileVar)GetProcAddress(HTTFILE,
120     MAKEINTRESOURCE(IdSetFileVar));
121     if (SetFileVar==NULL)
122     Err = TRUE;
123    
124     GetXFname = (PGetXFname)GetProcAddress(HTTFILE,
125     MAKEINTRESOURCE(IdGetXFname));
126     if (GetXFname==NULL)
127     Err = TRUE;
128    
129     ProtoInit = (PProtoInit)GetProcAddress(HTTFILE,
130     MAKEINTRESOURCE(IdProtoInit));
131     if (ProtoInit==NULL)
132     Err = TRUE;
133    
134     ProtoParse = (PProtoParse)GetProcAddress(HTTFILE,
135     MAKEINTRESOURCE(IdProtoParse));
136     if (ProtoParse==NULL)
137     Err = TRUE;
138    
139     ProtoTimeOutProc = (PProtoTimeOutProc)GetProcAddress(HTTFILE,
140     MAKEINTRESOURCE(IdProtoTimeOutProc));
141     if (ProtoTimeOutProc==NULL)
142     Err = TRUE;
143    
144     ProtoCancel = (PProtoCancel)GetProcAddress(HTTFILE,
145     MAKEINTRESOURCE(IdProtoCancel));
146     if (ProtoCancel==NULL)
147     Err = TRUE;
148    
149     if (Err)
150     {
151     FreeLibrary(HTTFILE);
152     HTTFILE = NULL;
153     return FALSE;
154     }
155     else {
156     TTFILECount = 1;
157     return TRUE;
158     }
159     }
160    
161     BOOL FreeTTFILE()
162     {
163     if (TTFILECount==0)
164     return FALSE;
165     TTFILECount--;
166     if (TTFILECount>0)
167     return TRUE;
168     if (HTTFILE!=NULL)
169     {
170     FreeLibrary(HTTFILE);
171     HTTFILE = NULL;
172     }
173     return TRUE;
174     }
175    
176     static PFileTransDlg FLogDlg = NULL;
177     static PFileTransDlg SendDlg = NULL;
178     static PProtoDlg PtDlg = NULL;
179    
180     BOOL OpenFTDlg(PFileVar fv)
181     {
182     PFileTransDlg FTDlg;
183     HWND HFTDlg;
184     char uimsg[MAX_UIMSG];
185    
186     FTDlg = new CFileTransDlg();
187    
188     if (FTDlg!=NULL)
189     {
190     FTDlg->Create(fv, &cv, &ts);
191     FTDlg->RefreshNum();
192     if (fv->HideDialog)
193     FTDlg->ShowWindow(SW_HIDE);
194     else if (fv->OpId == OpLog) {
195     FTDlg->ShowWindow(SW_MINIMIZE);
196     HWndLog = FTDlg->m_hWnd; // steven add
197     }
198     }
199    
200     if (fv->OpId==OpLog)
201     FLogDlg = FTDlg; /* Log */
202     else
203     SendDlg = FTDlg; /* File send */
204    
205     HFTDlg=FTDlg->GetSafeHwnd();
206    
207     GetDlgItemText(HFTDlg, IDC_TRANS_FILENAME, uimsg, sizeof(uimsg));
208     get_lang_msg("DLG_FILETRANS_FILENAME", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
209     SetDlgItemText(HFTDlg, IDC_TRANS_FILENAME, ts.UIMsg);
210     GetDlgItemText(HFTDlg, IDC_FULLPATH_LABEL, uimsg, sizeof(uimsg));
211     get_lang_msg("DLG_FILETRANS_FULLPATH", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
212     SetDlgItemText(HFTDlg, IDC_FULLPATH_LABEL, ts.UIMsg);
213     GetDlgItemText(HFTDlg, IDC_TRANS_TRANS, uimsg, sizeof(uimsg));
214     get_lang_msg("DLG_FILETRANS_TRNAS", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
215     SetDlgItemText(HFTDlg, IDC_TRANS_TRANS, ts.UIMsg);
216     GetDlgItemText(HFTDlg, IDCANCEL, uimsg, sizeof(uimsg));
217     get_lang_msg("BTN_CANCEL", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
218     SetDlgItemText(HFTDlg, IDCANCEL, ts.UIMsg);
219     GetDlgItemText(HFTDlg, IDC_TRANSPAUSESTART, uimsg, sizeof(uimsg));
220     get_lang_msg("DLG_FILETRANS_PAUSE", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
221     SetDlgItemText(HFTDlg, IDC_TRANSPAUSESTART, ts.UIMsg);
222     GetDlgItemText(HFTDlg, IDC_TRANSHELP, uimsg, sizeof(uimsg));
223     get_lang_msg("BTN_HELP", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
224     SetDlgItemText(HFTDlg, IDC_TRANSHELP, ts.UIMsg);
225    
226 doda 2576 if (fv->OpId == OpSendFile) {
227     InitDlgProgress(HFTDlg, IDC_TRANSPROGRESS, &fv->ProgStat);
228     }
229     else {
230     fv->ProgStat = -1;
231     }
232    
233 maya 2476 return (FTDlg!=NULL);
234     }
235    
236     void ShowFTDlg(WORD OpId)
237     {
238     if (OpId == OpLog) {
239     if (FLogDlg != NULL) {
240     FLogDlg->ShowWindow(SW_SHOWNORMAL);
241     }
242     }
243     else {
244     if (SendDlg != NULL) {
245     SendDlg->ShowWindow(SW_SHOWNORMAL);
246     }
247     }
248     }
249    
250     BOOL NewFileVar(PFileVar *fv)
251     {
252     if ((*fv)==NULL)
253     {
254     *fv = (PFileVar)malloc(sizeof(TFileVar));
255     if ((*fv)!=NULL)
256     {
257     memset(*fv, 0, sizeof(TFileVar));
258     strncpy_s((*fv)->FullName, sizeof((*fv)->FullName),ts.FileDir, _TRUNCATE);
259     AppendSlash((*fv)->FullName,sizeof((*fv)->FullName));
260     (*fv)->DirLen = strlen((*fv)->FullName);
261     (*fv)->FileOpen = FALSE;
262     (*fv)->OverWrite = ((ts.FTFlag & FT_RENAME) == 0);
263     (*fv)->HMainWin = HVTWin;
264     (*fv)->Success = FALSE;
265     (*fv)->NoMsg = FALSE;
266     (*fv)->HideDialog = FALSE;
267     }
268     }
269    
270     return ((*fv)!=NULL);
271     }
272    
273     void FreeFileVar(PFileVar *fv)
274     {
275     if ((*fv)!=NULL)
276     {
277     if ((*fv)->FileOpen) _lclose((*fv)->FileHandle);
278     if ((*fv)->FnStrMemHandle>0)
279     {
280     GlobalUnlock((*fv)->FnStrMemHandle);
281     GlobalFree((*fv)->FnStrMemHandle);
282     }
283     free(*fv);
284     *fv = NULL;
285     }
286     }
287    
288     // &h ���z�X�g�����u�� (2007.5.14)
289     void ConvertLogname(char *c, int destlen)
290     {
291     char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
292    
293     memset(buf, 0, sizeof(buf));
294    
295     while(*p != '\0') {
296     if (*p == '&' && *(p+1) != '\0') {
297     switch (*(p+1)) {
298     case 'h':
299     if (cv.Open) {
300     if (cv.PortType == IdTCPIP) {
301     strncat_s(buf,sizeof(buf),ts.HostName,_TRUNCATE);
302     }
303     else if (cv.PortType == IdSerial) {
304     strncpy_s(buf2,sizeof(buf2),buf,_TRUNCATE);
305     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%sCOM%d", buf2, ts.ComPort);
306     }
307     }
308     break;
309     default:
310     strncpy_s(buf2,sizeof(buf2),p,2);
311     strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
312     }
313     p++;
314     }
315     else {
316     strncpy_s(buf2,sizeof(buf2),p,1);
317     strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
318     }
319     p++;
320     }
321     strncpy_s(c, destlen, buf, _TRUNCATE);
322     }
323    
324 maya 2602 void FixLogOption()
325     {
326     if (ts.TransBin) {
327     ts.LogTypePlainText = false;
328     ts.LogTimestamp = false;
329     }
330     }
331    
332 maya 2476 extern "C" {
333 maya 2635 BOOL LogStart()
334 maya 2476 {
335     LONG Option;
336     char *logdir;
337    
338 maya 2635 if ((FileLog) || (BinLog)) return FALSE;
339 maya 2476
340 maya 2635 if (! LoadTTFILE()) return FALSE;
341 maya 2476 if (! NewFileVar(&LogVar))
342     {
343     FreeTTFILE();
344 maya 2635 return FALSE;
345 maya 2476 }
346     LogVar->OpId = OpLog;
347    
348     if (strlen(ts.LogDefaultPath) > 0) {
349     logdir = ts.LogDefaultPath;
350     }
351     else if (strlen(ts.FileDir) > 0) {
352     logdir = ts.FileDir;
353     }
354     else {
355     logdir = ts.HomeDir;
356     }
357    
358     if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0)
359     {
360     // LOWORD
361     // 0x0001 = Binary
362     // HIWORD
363     // 0x0001 = Append
364     // 0x1000 = plain text (2005.2.20 yutaka)
365     // 0x2000 = timestamp (2006.7.23 maya)
366     // 0x4000 = hide file transfer dialog (2008.1.30 maya)
367     // teraterm.ini�����������������f�t�H���g�I�v�V�������������B(2005.5.7 yutaka)
368     Option = MAKELONG(ts.TransBin,
369     ts.Append |
370     (0x1000 * ts.LogTypePlainText) |
371     (0x2000 * ts.LogTimestamp) |
372     (0x4000 * ts.LogHideDialog));
373    
374     // ���O���f�t�H���g�t�@�C���������� (2006.8.28 maya)
375     strncat_s(LogVar->FullName, sizeof(LogVar->FullName), ts.LogDefaultName, _TRUNCATE);
376    
377     ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
378    
379     // &h ���z�X�g�����u�� (2007.5.14)
380     ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
381    
382     strncpy_s(LogVar->LogDefaultPath, sizeof(LogVar->LogDefaultPath), ts.LogDefaultPath, _TRUNCATE);
383     if (! (*GetTransFname)(LogVar, logdir, GTF_LOG, &Option))
384     {
385     FreeFileVar(&LogVar);
386     FreeTTFILE();
387 maya 2635 return FALSE;
388 maya 2476 }
389     ts.TransBin = LOWORD(Option);
390     ts.Append = HIWORD(Option);
391    
392     if (ts.Append & 0x1000) {
393     ts.LogTypePlainText = 1;
394     } else {
395     ts.LogTypePlainText = 0;
396     }
397    
398     if (ts.Append & 0x2000) {
399     ts.LogTimestamp = 1;
400     }
401     else {
402     ts.LogTimestamp = 0;
403     }
404    
405     if (ts.Append & 0x4000) {
406     ts.LogHideDialog = 1;
407     }
408     else {
409     ts.LogHideDialog = 0;
410     }
411    
412     ts.Append &= 0x1; // 1bit���}�X�N����
413    
414     }
415     else {
416     // LogVar->DirLen = 0 ��������������
417     // �t���p�X�E�����p�X������ LogVar->FullName �������������K�v������
418     char FileName[MAX_PATH];
419    
420     // �t���p�X��
421     strncpy_s(FileName, sizeof(FileName), LogVar->FullName, _TRUNCATE);
422     ConvFName(logdir,FileName,sizeof(FileName),"",LogVar->FullName,sizeof(LogVar->FullName));
423    
424     ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
425    
426     // &h ���z�X�g�����u�� (2007.5.14)
427     ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
428     (*SetFileVar)(LogVar);
429 maya 2602
430     FixLogOption();
431 maya 2476 }
432    
433     if (ts.TransBin > 0)
434     {
435     BinLog = TRUE;
436     FileLog = FALSE;
437     if (! CreateBinBuf())
438     {
439     FileTransEnd(OpLog);
440 maya 2635 return FALSE;
441 maya 2476 }
442     }
443     else {
444     BinLog = FALSE;
445     FileLog = TRUE;
446     if (! CreateLogBuf())
447     {
448     FileTransEnd(OpLog);
449 maya 2635 return FALSE;
450 maya 2476 }
451     }
452     cv.LStart = cv.LogPtr;
453     cv.LCount = 0;
454     if (ts.LogHideDialog)
455     LogVar->HideDialog = 1;
456    
457     HelpId = HlpFileLog;
458     /* 2007.05.24 Gentaro */
459     eLineEnd = Line_LineHead;
460    
461     if (ts.Append > 0)
462     {
463     LogVar->FileHandle = _lopen(LogVar->FullName,OF_WRITE);
464     if (LogVar->FileHandle>0){
465     _llseek(LogVar->FileHandle,0,2);
466     /* 2007.05.24 Gentaro
467     If log file already exists,
468     a newline is inserted before the first timestamp.
469     */
470     eLineEnd = Line_FileHead;
471     }
472     else
473     LogVar->FileHandle = _lcreat(LogVar->FullName,0);
474     }
475     else
476     LogVar->FileHandle = _lcreat(LogVar->FullName,0);
477     LogVar->FileOpen = (LogVar->FileHandle>0);
478     if (! LogVar->FileOpen)
479     {
480 yutakapon 2557 char msg[128];
481    
482     // �t�@�C���I�[�v���G���[�������b�Z�[�W�\�������������B(2008.7.9 yutaka)
483     if (LogVar->NoMsg == FALSE) {
484     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Can not create a `%s' file. (%d)", LogVar->FullName, GetLastError());
485     MessageBox(NULL, msg, "Tera Term: File open error", MB_OK | MB_ICONERROR);
486     }
487    
488 maya 2476 FileTransEnd(OpLog);
489 maya 2635 return FALSE;
490 maya 2476 }
491     LogVar->ByteCount = 0;
492    
493 maya 2635 if (! OpenFTDlg(LogVar)) {
494 maya 2476 FileTransEnd(OpLog);
495 maya 2635 return FALSE;
496     }
497    
498     return TRUE;
499 maya 2476 }
500     }
501    
502     void LogPut1(BYTE b)
503     {
504     LogLast = b;
505     cv.LogBuf[cv.LogPtr] = b;
506     cv.LogPtr++;
507     if (cv.LogPtr>=InBuffSize)
508     cv.LogPtr = cv.LogPtr-InBuffSize;
509    
510     if (FileLog)
511     {
512     if (cv.LCount>=InBuffSize)
513     {
514     cv.LCount = InBuffSize;
515     cv.LStart = cv.LogPtr;
516     }
517     else
518     cv.LCount++;
519     }
520     else
521     cv.LCount = 0;
522    
523     if (DDELog)
524     {
525     if (cv.DCount>=InBuffSize)
526     {
527     cv.DCount = InBuffSize;
528     cv.DStart = cv.LogPtr;
529     }
530     else
531     cv.DCount++;
532     }
533     else {
534     cv.DCount = 0;
535     // ���O���������}�N�����X�g�[���������������C���B
536     // ���O�����������x�}�N�����~�������A�o�b�t�@���C���f�b�N�X�������������������A
537     // ���x�}�N�������������������f�[�^�������������������B
538     // �}�N�������~���������������C���f�b�N�X�����������������������B
539     // (2006.12.26 yutaka)
540     cv.DStart = cv.LogPtr;
541     }
542     }
543    
544     void Log1Byte(BYTE b)
545     {
546     if (b==0x0d)
547     {
548     LogLast = b;
549     return;
550     }
551     if ((b==0x0a) && (LogLast==0x0d))
552     LogPut1(0x0d);
553     LogPut1(b);
554     }
555    
556     static BOOL Get1(PCHAR Buf, int *Start, int *Count, PBYTE b)
557     {
558     if (*Count<=0) return FALSE;
559     *b = Buf[*Start];
560     (*Start)++;
561     if (*Start>=InBuffSize)
562     *Start = *Start-InBuffSize;
563     (*Count)--;
564     return TRUE;
565     }
566    
567    
568    
569     static CRITICAL_SECTION g_filelog_lock; /* ���b�N�p���� */
570    
571     void logfile_lock_initialize(void)
572     {
573     InitializeCriticalSection(&g_filelog_lock);
574     }
575    
576     static inline void logfile_lock(void)
577     {
578     EnterCriticalSection(&g_filelog_lock);
579     }
580    
581     static inline void logfile_unlock(void)
582     {
583     LeaveCriticalSection(&g_filelog_lock);
584     }
585    
586     // �R�����g�����O����������
587     void CommentLogToFile(char *buf, int size)
588     {
589     DWORD wrote;
590    
591     if (LogVar == NULL || !LogVar->FileOpen) {
592     char uimsg[MAX_UIMSG];
593     get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
594     get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
595     "It is not opened by the log file yet.", ts.UILanguageFile);
596     ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
597     return;
598     }
599    
600     logfile_lock();
601     WriteFile((HANDLE)LogVar->FileHandle, buf, size, &wrote, NULL);
602     WriteFile((HANDLE)LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
603     /* Set Line End Flag
604     2007.05.24 Gentaro
605     */
606     eLineEnd = Line_LineHead;
607     logfile_unlock();
608     }
609    
610     void LogToFile()
611     {
612     PCHAR Buf;
613     int Start, Count;
614     BYTE b;
615    
616     if (! LogVar->FileOpen) return;
617     if (FileLog)
618     {
619     Buf = cv.LogBuf;
620     Start = cv.LStart;
621     Count = cv.LCount;
622     }
623     else if (BinLog)
624     {
625     Buf = cv.BinBuf;
626     Start = cv.BStart;
627     Count = cv.BCount;
628     }
629     else
630     return;
631    
632     if (Buf==NULL) return;
633     if (Count==0) return;
634    
635     // ���b�N������(2004.8.6 yutaka)
636     logfile_lock();
637    
638     while (Get1(Buf,&Start,&Count,&b))
639     {
640     if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
641     {
642     // �����������o��(2006.7.23 maya)
643     // ���t�t�H�[�}�b�g�����{�����������E�W�������X���� (2006.7.23 yutaka)
644     /* 2007.05.24 Gentaro */
645     if ( ts.LogTimestamp && eLineEnd ) {
646     #if 0
647     SYSTEMTIME LocalTime;
648     GetLocalTime(&LocalTime);
649     char strtime[27];
650    
651     // format time
652     sprintf(strtime, "[%04d/%02d/%02d %02d:%02d:%02d.%03d] ",
653     LocalTime.wYear, LocalTime.wMonth,LocalTime.wDay,
654     LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond,
655     LocalTime.wMilliseconds);
656     #else
657     time_t tick = time(NULL);
658     char *strtime = ctime(&tick);
659     #endif
660     /* 2007.05.24 Gentaro */
661     if( eLineEnd == Line_FileHead ){
662     _lwrite(LogVar->FileHandle,"\r\n",2);
663     }
664     _lwrite(LogVar->FileHandle,"[",1);
665     // �����������������I�[�� \n ���������������������������B
666     _lwrite(LogVar->FileHandle, strtime, strlen(strtime) - 1);
667     _lwrite(LogVar->FileHandle,"] ",2);
668     }
669    
670     /* 2007.05.24 Gentaro */
671     if( b == 0x0a ){
672     eLineEnd = Line_LineHead; /* set endmark*/
673     }
674     else {
675     eLineEnd = Line_Other; /* clear endmark*/
676     }
677    
678     _lwrite(LogVar->FileHandle,(PCHAR)&b,1);
679     (LogVar->ByteCount)++;
680     }
681     }
682    
683     logfile_unlock();
684    
685     if (FileLog)
686     {
687     cv.LStart = Start;
688     cv.LCount = Count;
689     }
690     else {
691     cv.BStart = Start;
692     cv.BCount = Count;
693     }
694     if (((cv.FilePause & OpLog) !=0) || cv.ProtoFlag) return;
695     if (FLogDlg!=NULL)
696     FLogDlg->RefreshNum();
697     }
698    
699     BOOL CreateLogBuf()
700     {
701     if (cv.HLogBuf==NULL)
702     {
703     cv.HLogBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
704     cv.LogBuf = NULL;
705     cv.LogPtr = 0;
706     cv.LStart = 0;
707     cv.LCount = 0;
708     cv.DStart = 0;
709     cv.DCount = 0;
710     }
711     return (cv.HLogBuf!=NULL);
712     }
713    
714     void FreeLogBuf()
715     {
716     if ((cv.HLogBuf==NULL) || FileLog || DDELog)
717     return;
718     if (cv.LogBuf!=NULL)
719     GlobalUnlock(cv.HLogBuf);
720     GlobalFree(cv.HLogBuf);
721     cv.HLogBuf = NULL;
722     cv.LogBuf = NULL;
723     cv.LogPtr = 0;
724     cv.LStart = 0;
725     cv.LCount = 0;
726     cv.DStart = 0;
727     cv.DCount = 0;
728     }
729    
730     BOOL CreateBinBuf()
731     {
732     if (cv.HBinBuf==NULL)
733     {
734     cv.HBinBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
735     cv.BinBuf = NULL;
736     cv.BinPtr = 0;
737     cv.BStart = 0;
738     cv.BCount = 0;
739     }
740     return (cv.HBinBuf!=NULL);
741     }
742    
743     void FreeBinBuf()
744     {
745     if ((cv.HBinBuf==NULL) || BinLog)
746     return;
747     if (cv.BinBuf!=NULL)
748     GlobalUnlock(cv.HBinBuf);
749     GlobalFree(cv.HBinBuf);
750     cv.HBinBuf = NULL;
751     cv.BinBuf = NULL;
752     cv.BinPtr = 0;
753     cv.BStart = 0;
754     cv.BCount = 0;
755     }
756    
757     extern "C" {
758     void FileSendStart()
759     {
760     LONG Option;
761    
762     if (! cv.Ready || FSend) return;
763     if (cv.ProtoFlag)
764     {
765     FreeFileVar(&SendVar);
766     return;
767     }
768    
769     if (! LoadTTFILE())
770     return;
771     if (! NewFileVar(&SendVar))
772     {
773     FreeTTFILE();
774     return;
775     }
776     SendVar->OpId = OpSendFile;
777    
778     FSend = TRUE;
779    
780     if (strlen(&(SendVar->FullName[SendVar->DirLen]))==0)
781     {
782     Option = MAKELONG(ts.TransBin,0);
783     SendVar->FullName[0] = 0;
784     if (! (*GetTransFname)(SendVar, ts.FileDir, GTF_SEND, &Option))
785     {
786     FileTransEnd(OpSendFile);
787     return;
788     }
789     ts.TransBin = LOWORD(Option);
790     }
791     else
792     (*SetFileVar)(SendVar);
793    
794     SendVar->FileHandle = _lopen(SendVar->FullName,OF_READ);
795     SendVar->FileOpen = (SendVar->FileHandle>0);
796     if (! SendVar->FileOpen)
797     {
798     FileTransEnd(OpSendFile);
799     return;
800     }
801     SendVar->ByteCount = 0;
802 doda 2576 SendVar->FileSize = GetFSize(SendVar->FullName);
803 maya 2476
804     TalkStatus = IdTalkFile;
805     FileRetrySend = FALSE;
806     FileRetryEcho = FALSE;
807     FileCRSend = FALSE;
808    
809     if (! OpenFTDlg(SendVar))
810     FileTransEnd(OpSendFile);
811     }
812     }
813    
814     void FileTransEnd(WORD OpId)
815     /* OpId = 0: close Log and FileSend
816     OpLog: close Log
817     OpSendFile: close FileSend */
818     {
819     if (((OpId==0) || (OpId==OpLog)) && (FileLog || BinLog))
820     {
821     FileLog = FALSE;
822     BinLog = FALSE;
823     if (FLogDlg!=NULL)
824     {
825     FLogDlg->DestroyWindow();
826     FLogDlg = NULL;
827     HWndLog = NULL; // steven add
828     }
829     FreeFileVar(&LogVar);
830     FreeLogBuf();
831     FreeBinBuf();
832     FreeTTFILE();
833     }
834    
835     if (((OpId==0) || (OpId==OpSendFile)) && FSend)
836     {
837     FSend = FALSE;
838     TalkStatus = IdTalkKeyb;
839     if (SendDlg!=NULL)
840     {
841     SendDlg->DestroyWindow();
842     SendDlg = NULL;
843     }
844     FreeFileVar(&SendVar);
845     FreeTTFILE();
846     }
847    
848     EndDdeCmnd(0);
849     }
850    
851     // vtwin.cpp �����R�[�������������Aextern "C"���t�����B(2004.11.3 yutaka)
852     extern "C" {
853     int FSOut1(BYTE b)
854     {
855     if (ts.TransBin > 0)
856     return CommBinaryOut(&cv,(PCHAR)&b,1);
857     else if ((b>=0x20) || (b==0x09) || (b==0x0A) || (b==0x0D))
858     return CommTextOut(&cv,(PCHAR)&b,1);
859     else
860     return 1;
861     }
862    
863     int FSEcho1(BYTE b)
864     {
865     if (ts.TransBin > 0)
866     return CommBinaryEcho(&cv,(PCHAR)&b,1);
867     else
868     return CommTextEcho(&cv,(PCHAR)&b,1);
869     }
870     }
871    
872     extern "C" {
873     void FileSend()
874     {
875     WORD c, fc;
876     LONG BCOld;
877    
878     if ((SendDlg==NULL) ||
879     ((cv.FilePause & OpSendFile) !=0))
880     return;
881    
882     BCOld = SendVar->ByteCount;
883    
884     if (FileRetrySend)
885     {
886     FileRetryEcho = (ts.LocalEcho>0);
887     c = FSOut1(FileByte);
888     FileRetrySend = (c==0);
889     if (FileRetrySend)
890     return;
891     }
892    
893     if (FileRetryEcho)
894     {
895     c = FSEcho1(FileByte);
896     FileRetryEcho = (c==0);
897     if (FileRetryEcho)
898     return;
899     }
900    
901     do {
902     fc = _lread(SendVar->FileHandle,&FileByte,1);
903     SendVar->ByteCount = SendVar->ByteCount + fc;
904    
905     if (FileCRSend && (fc==1) && (FileByte==0x0A))
906     {
907     fc = _lread(SendVar->FileHandle,&FileByte,1);
908     SendVar->ByteCount = SendVar->ByteCount + fc;
909     }
910    
911     if (fc!=0)
912     {
913     c = FSOut1(FileByte);
914     FileCRSend = (ts.TransBin==0) && (FileByte==0x0D);
915     FileRetrySend = (c==0);
916     if (FileRetrySend)
917     {
918     if (SendVar->ByteCount != BCOld)
919     SendDlg->RefreshNum();
920     return;
921     }
922     if (ts.LocalEcho>0)
923     {
924     c = FSEcho1(FileByte);
925     FileRetryEcho = (c==0);
926     if (FileRetryEcho)
927     return;
928     }
929     }
930     if ((fc==0) || (SendVar->ByteCount % 100 == 0))
931     {
932     SendDlg->RefreshNum();
933     BCOld = SendVar->ByteCount;
934     if (fc!=0)
935     return;
936     }
937     } while (fc!=0);
938    
939     FileTransEnd(OpSendFile);
940     }
941     }
942    
943     extern "C" {
944     void FLogChangeButton(BOOL Pause)
945     {
946     if (FLogDlg!=NULL)
947     FLogDlg->ChangeButton(Pause);
948     }
949     }
950    
951     extern "C" {
952     void FLogRefreshNum()
953     {
954     if (FLogDlg!=NULL)
955     FLogDlg->RefreshNum();
956     }
957     }
958    
959     BOOL OpenProtoDlg(PFileVar fv, int IdProto, int Mode, WORD Opt1, WORD Opt2)
960     {
961     int vsize;
962     PProtoDlg pd;
963     HWND Hpd;
964     char uimsg[MAX_UIMSG];
965    
966     ProtoId = IdProto;
967    
968     switch (ProtoId) {
969     case PROTO_KMT:
970     vsize = sizeof(TKmtVar);
971     break;
972     case PROTO_XM:
973     vsize = sizeof(TXVar);
974     break;
975 yutakapon 2511 case PROTO_YM:
976     vsize = sizeof(TYVar);
977     break;
978 maya 2476 case PROTO_ZM:
979     vsize = sizeof(TZVar);
980     break;
981     case PROTO_BP:
982     vsize = sizeof(TBPVar);
983     break;
984     case PROTO_QV:
985     vsize = sizeof(TQVVar);
986     break;
987     }
988     ProtoVar = (PCHAR)malloc(vsize);
989     if (ProtoVar==NULL)
990     return FALSE;
991    
992     switch (ProtoId) {
993     case PROTO_KMT:
994     ((PKmtVar)ProtoVar)->KmtMode = Mode;
995     break;
996     case PROTO_XM:
997     ((PXVar)ProtoVar)->XMode = Mode;
998     ((PXVar)ProtoVar)->XOpt = Opt1;
999     ((PXVar)ProtoVar)->TextFlag = 1 - (Opt2 & 1);
1000     break;
1001 yutakapon 2511 case PROTO_YM: // TBD
1002     ((PYVar)ProtoVar)->YMode = Mode;
1003 yutakapon 2512 ((PYVar)ProtoVar)->YOpt = Yopt1K; // TBD
1004 yutakapon 2511 break;
1005 maya 2476 case PROTO_ZM:
1006     ((PZVar)ProtoVar)->BinFlag = (Opt1 & 1) != 0;
1007     ((PZVar)ProtoVar)->ZMode = Mode;
1008     break;
1009     case PROTO_BP:
1010     ((PBPVar)ProtoVar)->BPMode = Mode;
1011     break;
1012     case PROTO_QV:
1013     ((PQVVar)ProtoVar)->QVMode = Mode;
1014     break;
1015     }
1016    
1017     pd = new CProtoDlg();
1018     if (pd==NULL)
1019     {
1020     free(ProtoVar);
1021     ProtoVar = NULL;
1022     return FALSE;
1023     }
1024     pd->Create(fv,&ts);
1025    
1026     Hpd=pd->GetSafeHwnd();
1027    
1028     GetDlgItemText(Hpd, IDC_PROT_FILENAME, uimsg, sizeof(uimsg));
1029     get_lang_msg("DLG_PROT_FIELNAME", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1030     SetDlgItemText(Hpd, IDC_PROT_FILENAME, ts.UIMsg);
1031     GetDlgItemText(Hpd, IDC_PROT_PROT, uimsg, sizeof(uimsg));
1032     get_lang_msg("DLG_PROT_PROTO", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1033     SetDlgItemText(Hpd, IDC_PROT_PROT, ts.UIMsg);
1034     GetDlgItemText(Hpd, IDC_PROT_PACKET, uimsg, sizeof(uimsg));
1035     get_lang_msg("DLG_PROT_PACKET", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1036     SetDlgItemText(Hpd, IDC_PROT_PACKET, ts.UIMsg);
1037     GetDlgItemText(Hpd, IDC_PROT_TRANS, uimsg, sizeof(uimsg));
1038     get_lang_msg("DLG_PROT_TRANS", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1039     SetDlgItemText(Hpd, IDC_PROT_TRANS, ts.UIMsg);
1040     GetDlgItemText(Hpd, IDCANCEL, uimsg, sizeof(uimsg));
1041     get_lang_msg("BTN_CANCEL", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1042     SetDlgItemText(Hpd, IDCANCEL, ts.UIMsg);
1043    
1044     (*ProtoInit)(ProtoId,FileVar,ProtoVar,&cv,&ts);
1045    
1046     PtDlg = pd;
1047     return TRUE;
1048     }
1049    
1050     extern "C" {
1051     void CloseProtoDlg()
1052     {
1053     if (PtDlg!=NULL)
1054     {
1055     PtDlg->DestroyWindow();
1056     PtDlg = NULL;
1057    
1058     ::KillTimer(FileVar->HMainWin,IdProtoTimer);
1059     if ((ProtoId==PROTO_QV) &&
1060     (((PQVVar)ProtoVar)->QVMode==IdQVSend))
1061     CommTextOut(&cv,"\015",1);
1062     if (FileVar->LogFlag)
1063     _lclose(FileVar->LogFile);
1064     FileVar->LogFile = 0;
1065     if (ProtoVar!=NULL)
1066     {
1067     free(ProtoVar);
1068     ProtoVar = NULL;
1069     }
1070     }
1071     }
1072     }
1073    
1074     BOOL ProtoStart()
1075     {
1076     if (cv.ProtoFlag)
1077     return FALSE;
1078     if (FSend)
1079     {
1080     FreeFileVar(&FileVar);
1081     return FALSE;
1082     }
1083    
1084     if (! LoadTTFILE())
1085     return FALSE;
1086     NewFileVar(&FileVar);
1087    
1088     if (FileVar==NULL)
1089     {
1090     FreeTTFILE();
1091     return FALSE;
1092     }
1093     cv.ProtoFlag = TRUE;
1094     return TRUE;
1095     }
1096    
1097     void ProtoEnd()
1098     {
1099     if (! cv.ProtoFlag)
1100     return;
1101     cv.ProtoFlag = FALSE;
1102    
1103     /* Enable transmit delay (serial port) */
1104     cv.DelayFlag = TRUE;
1105     TalkStatus = IdTalkKeyb;
1106    
1107     CloseProtoDlg();
1108    
1109     if ((FileVar!=NULL) && FileVar->Success)
1110     EndDdeCmnd(1);
1111     else
1112     EndDdeCmnd(0);
1113    
1114     FreeTTFILE();
1115     FreeFileVar(&FileVar);
1116     }
1117    
1118     extern "C" {
1119     int ProtoDlgParse()
1120     {
1121     int P;
1122    
1123     P = ActiveWin;
1124     if (PtDlg==NULL)
1125     return P;
1126    
1127     if ((*ProtoParse)(ProtoId,FileVar,ProtoVar,&cv))
1128     P = 0; /* continue */
1129     else {
1130     CommSend(&cv);
1131     ProtoEnd();
1132     }
1133     return P;
1134     }
1135     }
1136    
1137     extern "C" {
1138     void ProtoDlgTimeOut()
1139     {
1140     if (PtDlg!=NULL)
1141     (*ProtoTimeOutProc)(ProtoId,FileVar,ProtoVar,&cv);
1142     }
1143     }
1144    
1145     extern "C" {
1146     void ProtoDlgCancel()
1147     {
1148     if ((PtDlg!=NULL) &&
1149     (*ProtoCancel)(ProtoId,FileVar,ProtoVar,&cv))
1150     ProtoEnd();
1151     }
1152     }
1153    
1154     extern "C" {
1155     void KermitStart(int mode)
1156     {
1157     WORD w;
1158    
1159     if (! ProtoStart())
1160     return;
1161    
1162     switch (mode) {
1163     case IdKmtSend:
1164     FileVar->OpId = OpKmtSend;
1165     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1166     {
1167     if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_KERMIT,&w) ||
1168     (FileVar->NumFname==0))
1169     {
1170     ProtoEnd();
1171     return;
1172     }
1173     }
1174     else
1175     (*SetFileVar)(FileVar);
1176     break;
1177     case IdKmtReceive:
1178     FileVar->OpId = OpKmtRcv;
1179     break;
1180     case IdKmtGet:
1181     FileVar->OpId = OpKmtSend;
1182     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1183     {
1184     if (! (*GetGetFname)(FileVar->HMainWin,FileVar) ||
1185     (strlen(FileVar->FullName)==0))
1186     {
1187     ProtoEnd();
1188     return;
1189     }
1190     }
1191     else
1192     (*SetFileVar)(FileVar);
1193     break;
1194     case IdKmtFinish:
1195     FileVar->OpId = OpKmtFin;
1196     break;
1197     default:
1198     ProtoEnd();
1199     return;
1200     }
1201     TalkStatus = IdTalkQuiet;
1202    
1203     /* disable transmit delay (serial port) */
1204     cv.DelayFlag = FALSE;
1205    
1206     if (! OpenProtoDlg(FileVar,PROTO_KMT,mode,0,0))
1207     ProtoEnd();
1208     }
1209     }
1210    
1211     extern "C" {
1212     void XMODEMStart(int mode)
1213     {
1214     LONG Option;
1215    
1216     if (! ProtoStart())
1217     return;
1218    
1219     if (mode==IdXReceive)
1220     FileVar->OpId = OpXRcv;
1221     else
1222     FileVar->OpId = OpXSend;
1223    
1224     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1225     {
1226     Option = MAKELONG(ts.XmodemBin,ts.XmodemOpt);
1227     if (! (*GetXFname)(FileVar->HMainWin,
1228     mode==IdXReceive,&Option,FileVar,ts.FileDir))
1229     {
1230     ProtoEnd();
1231     return;
1232     }
1233     ts.XmodemOpt = HIWORD(Option);
1234     ts.XmodemBin = LOWORD(Option);
1235     }
1236     else
1237     (*SetFileVar)(FileVar);
1238    
1239     if (mode==IdXReceive)
1240     FileVar->FileHandle = _lcreat(FileVar->FullName,0);
1241     else
1242     FileVar->FileHandle = _lopen(FileVar->FullName,OF_READ);
1243    
1244     FileVar->FileOpen = FileVar->FileHandle>0;
1245     if (! FileVar->FileOpen)
1246     {
1247     ProtoEnd();
1248     return;
1249     }
1250     TalkStatus = IdTalkQuiet;
1251    
1252     /* disable transmit delay (serial port) */
1253     cv.DelayFlag = FALSE;
1254    
1255     if (! OpenProtoDlg(FileVar,PROTO_XM,mode,
1256     ts.XmodemOpt,ts.XmodemBin))
1257     ProtoEnd();
1258     }
1259     }
1260    
1261     extern "C" {
1262 yutakapon 2511 void YMODEMStart(int mode)
1263     {
1264 yutakapon 2512 WORD Opt;
1265 yutakapon 2511
1266     if (! ProtoStart())
1267     return;
1268    
1269 yutakapon 2512 if (mode==IdYSend)
1270     {
1271     Opt = ts.XmodemBin;
1272 yutakapon 2511 FileVar->OpId = OpYSend;
1273 yutakapon 2512 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1274 yutakapon 2511 {
1275 yutakapon 2512 if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_Y,&Opt) ||
1276     (FileVar->NumFname==0))
1277     {
1278     ProtoEnd();
1279     return;
1280     }
1281     ts.XmodemBin = Opt;
1282 yutakapon 2511 }
1283 yutakapon 2512 else
1284     (*SetFileVar)(FileVar);
1285 yutakapon 2511 }
1286 yutakapon 2512 else /* IdZReceive or IdZAuto */
1287     FileVar->OpId = OpYRcv;
1288 yutakapon 2511
1289     TalkStatus = IdTalkQuiet;
1290    
1291     /* disable transmit delay (serial port) */
1292     cv.DelayFlag = FALSE;
1293    
1294 yutakapon 2512 if (! OpenProtoDlg(FileVar,PROTO_YM,mode,Opt,0))
1295 yutakapon 2511 ProtoEnd();
1296     }
1297     }
1298    
1299     extern "C" {
1300 maya 2476 void ZMODEMStart(int mode)
1301     {
1302     WORD Opt;
1303    
1304     if (! ProtoStart())
1305     return;
1306    
1307     if (mode==IdZSend)
1308     {
1309     Opt = ts.XmodemBin;
1310     FileVar->OpId = OpZSend;
1311     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1312     {
1313     if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_Z,&Opt) ||
1314     (FileVar->NumFname==0))
1315     {
1316     ProtoEnd();
1317     return;
1318     }
1319     ts.XmodemBin = Opt;
1320     }
1321     else
1322     (*SetFileVar)(FileVar);
1323     }
1324     else /* IdZReceive or IdZAuto */
1325     FileVar->OpId = OpZRcv;
1326    
1327     TalkStatus = IdTalkQuiet;
1328    
1329     /* disable transmit delay (serial port) */
1330     cv.DelayFlag = FALSE;
1331    
1332     if (! OpenProtoDlg(FileVar,PROTO_ZM,mode,Opt,0))
1333     ProtoEnd();
1334     }
1335     }
1336    
1337     extern "C" {
1338     void BPStart(int mode)
1339     {
1340     LONG Option;
1341    
1342     if (! ProtoStart())
1343     return;
1344     if (mode==IdBPSend)
1345     {
1346     FileVar->OpId = OpBPSend;
1347     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1348     {
1349     FileVar->FullName[0] = 0;
1350     if (! (*GetTransFname)(FileVar, ts.FileDir, GTF_BP, &Option))
1351     {
1352     ProtoEnd();
1353     return;
1354     }
1355     }
1356     else
1357     (*SetFileVar)(FileVar);
1358     }
1359     else /* IdBPReceive or IdBPAuto */
1360     FileVar->OpId = OpBPRcv;
1361    
1362     TalkStatus = IdTalkQuiet;
1363    
1364     /* disable transmit delay (serial port) */
1365     cv.DelayFlag = FALSE;
1366    
1367     if (! OpenProtoDlg(FileVar,PROTO_BP,mode,0,0))
1368     ProtoEnd();
1369     }
1370     }
1371    
1372     extern "C" {
1373     void QVStart(int mode)
1374     {
1375     WORD W;
1376    
1377     if (! ProtoStart())
1378     return;
1379    
1380     if (mode==IdQVSend)
1381     {
1382     FileVar->OpId = OpQVSend;
1383     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1384     {
1385     if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_QV, &W) ||
1386     (FileVar->NumFname==0))
1387     {
1388     ProtoEnd();
1389     return;
1390     }
1391     }
1392     else
1393     (*SetFileVar)(FileVar);
1394     }
1395     else
1396     FileVar->OpId = OpQVRcv;
1397    
1398     TalkStatus = IdTalkQuiet;
1399    
1400     /* disable transmit delay (serial port) */
1401     cv.DelayFlag = FALSE;
1402    
1403     if (! OpenProtoDlg(FileVar,PROTO_QV,mode,0,0))
1404     ProtoEnd();
1405     }
1406     }

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