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 6435 - (hide annotations) (download) (as text)
Mon Jul 11 08:53:02 2016 UTC (7 years, 9 months ago) by doda
File MIME type: text/x-c++src
File size: 43724 byte(s)
・行末の空白/タブを削除
・インデント調整
1 maya 3227 /* 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     #include "dlglib.h"
20 doda 3904 #include "vtterm.h"
21 maya 3227
22     #include "filesys.h"
23     #include "ftlib.h"
24    
25 yutakapon 5392 #include "buffer.h"
26    
27 yutakapon 5162 #include <io.h>
28 yutakapon 5206 #include <process.h>
29 yutakapon 5162
30 doda 3904 #define FS_BRACKET_NONE 0
31     #define FS_BRACKET_START 1
32     #define FS_BRACKET_END 2
33    
34 maya 3227 PFileVar LogVar = NULL;
35     PFileVar SendVar = NULL;
36     PFileVar FileVar = NULL;
37     static PCHAR ProtoVar = NULL;
38     static int ProtoId;
39    
40     static BYTE LogLast = 0;
41     BOOL FileLog = FALSE;
42     BOOL BinLog = FALSE;
43     BOOL DDELog = FALSE;
44 doda 3904 static BOOL FileRetrySend, FileRetryEcho, FileCRSend, FileReadEOF, BinaryMode;
45 maya 3227 static BYTE FileByte;
46    
47 maya 6071 #define FILE_SEND_BUF_SIZE 8192
48     struct FileSendHandler {
49     CHAR buf[FILE_SEND_BUF_SIZE];
50     int pos;
51     int end;
52     };
53     static struct FileSendHandler FileSendHandler;
54     static int FileDlgRefresh;
55    
56 doda 3904 static int FileBracketMode = FS_BRACKET_NONE;
57     static int FileBracketPtr = 0;
58     static char BracketStartStr[] = "\033[200~";
59     static char BracketEndStr[] = "\033[201~";
60    
61 maya 3227 static BOOL FSend = FALSE;
62    
63 doda 6435 HWND HWndLog = NULL; //steven add
64 maya 3227
65     static HMODULE HTTFILE = NULL;
66     static int TTFILECount = 0;
67    
68     PGetSetupFname GetSetupFname;
69     PGetTransFname GetTransFname;
70     PGetMultiFname GetMultiFname;
71     PGetGetFname GetGetFname;
72     PSetFileVar SetFileVar;
73     PGetXFname GetXFname;
74     PProtoInit ProtoInit;
75     PProtoParse ProtoParse;
76     PProtoTimeOutProc ProtoTimeOutProc;
77     PProtoCancel ProtoCancel;
78    
79     #define IdGetSetupFname 1
80     #define IdGetTransFname 2
81     #define IdGetMultiFname 3
82     #define IdGetGetFname 4
83     #define IdSetFileVar 5
84     #define IdGetXFname 6
85    
86     #define IdProtoInit 7
87     #define IdProtoParse 8
88     #define IdProtoTimeOutProc 9
89     #define IdProtoCancel 10
90    
91     /*
92     Line Head flag for timestamping
93     2007.05.24 Gentaro
94     */
95     enum enumLineEnd {
96     Line_Other = 0,
97     Line_LineHead = 1,
98     Line_FileHead = 2,
99     };
100    
101     enum enumLineEnd eLineEnd = Line_LineHead;
102    
103 yutakapon 5206
104     // �x�����������p�X���b�h�����b�Z�[�W
105     #define WM_DPC_LOGTHREAD_SEND (WM_APP + 1)
106    
107     static void CloseFileSync(PFileVar ptr);
108    
109    
110 maya 3227 BOOL LoadTTFILE()
111     {
112     BOOL Err;
113    
114     if (HTTFILE != NULL)
115     {
116     TTFILECount++;
117     return TRUE;
118     }
119     else
120     TTFILECount = 0;
121    
122     HTTFILE = LoadLibrary("TTPFILE.DLL");
123     if (HTTFILE == NULL)
124     return FALSE;
125    
126     TTFILESetUILanguageFile(ts.UILanguageFile);
127     TTFILESetFileSendFilter(ts.FileSendFilter);
128    
129     Err = FALSE;
130     GetSetupFname = (PGetSetupFname)GetProcAddress(HTTFILE,
131     MAKEINTRESOURCE(IdGetSetupFname));
132     if (GetSetupFname==NULL)
133     Err = TRUE;
134    
135     GetTransFname = (PGetTransFname)GetProcAddress(HTTFILE,
136     MAKEINTRESOURCE(IdGetTransFname));
137     if (GetTransFname==NULL)
138     Err = TRUE;
139    
140     GetMultiFname = (PGetMultiFname)GetProcAddress(HTTFILE,
141     MAKEINTRESOURCE(IdGetMultiFname));
142     if (GetMultiFname==NULL)
143     Err = TRUE;
144    
145     GetGetFname = (PGetGetFname)GetProcAddress(HTTFILE,
146     MAKEINTRESOURCE(IdGetGetFname));
147     if (GetGetFname==NULL)
148     Err = TRUE;
149    
150     SetFileVar = (PSetFileVar)GetProcAddress(HTTFILE,
151     MAKEINTRESOURCE(IdSetFileVar));
152     if (SetFileVar==NULL)
153     Err = TRUE;
154    
155     GetXFname = (PGetXFname)GetProcAddress(HTTFILE,
156     MAKEINTRESOURCE(IdGetXFname));
157     if (GetXFname==NULL)
158     Err = TRUE;
159    
160     ProtoInit = (PProtoInit)GetProcAddress(HTTFILE,
161     MAKEINTRESOURCE(IdProtoInit));
162     if (ProtoInit==NULL)
163     Err = TRUE;
164    
165     ProtoParse = (PProtoParse)GetProcAddress(HTTFILE,
166     MAKEINTRESOURCE(IdProtoParse));
167     if (ProtoParse==NULL)
168     Err = TRUE;
169    
170     ProtoTimeOutProc = (PProtoTimeOutProc)GetProcAddress(HTTFILE,
171     MAKEINTRESOURCE(IdProtoTimeOutProc));
172     if (ProtoTimeOutProc==NULL)
173     Err = TRUE;
174    
175     ProtoCancel = (PProtoCancel)GetProcAddress(HTTFILE,
176     MAKEINTRESOURCE(IdProtoCancel));
177     if (ProtoCancel==NULL)
178     Err = TRUE;
179    
180     if (Err)
181     {
182     FreeLibrary(HTTFILE);
183     HTTFILE = NULL;
184 doda 6435 return FALSE;
185 maya 3227 }
186     else {
187     TTFILECount = 1;
188     return TRUE;
189     }
190     }
191    
192     BOOL FreeTTFILE()
193     {
194     if (TTFILECount==0)
195     return FALSE;
196     TTFILECount--;
197     if (TTFILECount>0)
198     return TRUE;
199     if (HTTFILE!=NULL)
200     {
201     FreeLibrary(HTTFILE);
202     HTTFILE = NULL;
203     }
204     return TRUE;
205     }
206    
207     static PFileTransDlg FLogDlg = NULL;
208     static PFileTransDlg SendDlg = NULL;
209     static PProtoDlg PtDlg = NULL;
210    
211     BOOL OpenFTDlg(PFileVar fv)
212     {
213     PFileTransDlg FTDlg;
214     HWND HFTDlg;
215     char uimsg[MAX_UIMSG];
216    
217     FTDlg = new CFileTransDlg();
218    
219 doda 4454 fv->StartTime = 0;
220     fv->ProgStat = 0;
221    
222 doda 5383 if (fv->OpId != OpLog) {
223     fv->HideDialog = ts.FTHideDialog;
224     }
225    
226 maya 3227 if (FTDlg!=NULL)
227     {
228     FTDlg->Create(fv, &cv, &ts);
229     FTDlg->RefreshNum();
230     if (fv->OpId == OpLog) {
231 doda 6435 HWndLog = FTDlg->m_hWnd; // steven add
232 maya 3227 }
233     }
234    
235     if (fv->OpId==OpLog)
236     FLogDlg = FTDlg; /* Log */
237     else
238     SendDlg = FTDlg; /* File send */
239    
240     HFTDlg=FTDlg->GetSafeHwnd();
241    
242     GetDlgItemText(HFTDlg, IDC_TRANS_FILENAME, uimsg, sizeof(uimsg));
243     get_lang_msg("DLG_FILETRANS_FILENAME", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
244     SetDlgItemText(HFTDlg, IDC_TRANS_FILENAME, ts.UIMsg);
245     GetDlgItemText(HFTDlg, IDC_FULLPATH_LABEL, uimsg, sizeof(uimsg));
246     get_lang_msg("DLG_FILETRANS_FULLPATH", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
247     SetDlgItemText(HFTDlg, IDC_FULLPATH_LABEL, ts.UIMsg);
248     GetDlgItemText(HFTDlg, IDC_TRANS_TRANS, uimsg, sizeof(uimsg));
249     get_lang_msg("DLG_FILETRANS_TRNAS", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
250     SetDlgItemText(HFTDlg, IDC_TRANS_TRANS, ts.UIMsg);
251 doda 4461 GetDlgItemText(HFTDlg, IDC_TRANS_ELAPSED, uimsg, sizeof(uimsg));
252     get_lang_msg("DLG_FILETRANS_ELAPSED", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
253     SetDlgItemText(HFTDlg, IDC_TRANS_ELAPSED, ts.UIMsg);
254 maya 3227 GetDlgItemText(HFTDlg, IDCANCEL, uimsg, sizeof(uimsg));
255 maya 3602 get_lang_msg("DLG_FILETRANS_CLOSE", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
256 maya 3227 SetDlgItemText(HFTDlg, IDCANCEL, ts.UIMsg);
257     GetDlgItemText(HFTDlg, IDC_TRANSPAUSESTART, uimsg, sizeof(uimsg));
258     get_lang_msg("DLG_FILETRANS_PAUSE", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
259     SetDlgItemText(HFTDlg, IDC_TRANSPAUSESTART, ts.UIMsg);
260     GetDlgItemText(HFTDlg, IDC_TRANSHELP, uimsg, sizeof(uimsg));
261     get_lang_msg("BTN_HELP", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
262     SetDlgItemText(HFTDlg, IDC_TRANSHELP, ts.UIMsg);
263    
264     if (fv->OpId == OpSendFile) {
265 doda 4454 fv->StartTime = GetTickCount();
266 maya 3227 InitDlgProgress(HFTDlg, IDC_TRANSPROGRESS, &fv->ProgStat);
267 doda 4461 ShowWindow(GetDlgItem(HFTDlg, IDC_TRANS_ELAPSED), SW_SHOW);
268 maya 3227 }
269    
270     return (FTDlg!=NULL);
271     }
272    
273     void ShowFTDlg(WORD OpId)
274     {
275     if (OpId == OpLog) {
276     if (FLogDlg != NULL) {
277     FLogDlg->ShowWindow(SW_SHOWNORMAL);
278 maya 3709 SetForegroundWindow(FLogDlg->GetSafeHwnd());
279 maya 3227 }
280     }
281     else {
282     if (SendDlg != NULL) {
283     SendDlg->ShowWindow(SW_SHOWNORMAL);
284 maya 3709 SetForegroundWindow(SendDlg->GetSafeHwnd());
285 maya 3227 }
286     }
287     }
288    
289     BOOL NewFileVar(PFileVar *fv)
290     {
291     if ((*fv)==NULL)
292     {
293     *fv = (PFileVar)malloc(sizeof(TFileVar));
294     if ((*fv)!=NULL)
295     {
296     memset(*fv, 0, sizeof(TFileVar));
297     strncpy_s((*fv)->FullName, sizeof((*fv)->FullName),ts.FileDir, _TRUNCATE);
298     AppendSlash((*fv)->FullName,sizeof((*fv)->FullName));
299     (*fv)->DirLen = strlen((*fv)->FullName);
300     (*fv)->FileOpen = FALSE;
301     (*fv)->OverWrite = ((ts.FTFlag & FT_RENAME) == 0);
302     (*fv)->HMainWin = HVTWin;
303     (*fv)->Success = FALSE;
304     (*fv)->NoMsg = FALSE;
305     (*fv)->HideDialog = FALSE;
306     }
307     }
308    
309     return ((*fv)!=NULL);
310     }
311    
312     void FreeFileVar(PFileVar *fv)
313     {
314     if ((*fv)!=NULL)
315     {
316 yutakapon 5206 CloseFileSync(*fv);
317     //if ((*fv)->FileOpen) _lclose((*fv)->FileHandle);
318 maya 3227 if ((*fv)->FnStrMemHandle>0)
319     {
320     GlobalUnlock((*fv)->FnStrMemHandle);
321     GlobalFree((*fv)->FnStrMemHandle);
322     }
323     free(*fv);
324     *fv = NULL;
325     }
326     }
327    
328     // &h ���z�X�g�����u�� (2007.5.14)
329 maya 3473 // &p ��TCP�|�[�g�������u�� (2009.6.12)
330 maya 3227 void ConvertLogname(char *c, int destlen)
331     {
332     char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
333 yutakapon 5139 char tmphost[1024];
334 maya 3227
335     memset(buf, 0, sizeof(buf));
336    
337     while(*p != '\0') {
338     if (*p == '&' && *(p+1) != '\0') {
339     switch (*(p+1)) {
340 maya 3473 case 'h':
341 maya 3227 if (cv.Open) {
342     if (cv.PortType == IdTCPIP) {
343 yutakapon 5139 // �z�X�g����IPv6�A�h���X�����A�t�@�C�������g�p�����������������������A
344     // �]�v�����������������B
345     // (2013.3.9 yutaka)
346     strncpy_s(tmphost, sizeof(tmphost), ts.HostName, _TRUNCATE);
347     //strncpy_s(tmphost, sizeof(tmphost), "2001:0db8:bd05:01d2:288a:1fc0:0001:10ee", _TRUNCATE);
348 maya 5141 replaceInvalidFileNameChar(tmphost, '_');
349 yutakapon 5139 strncat_s(buf,sizeof(buf), tmphost, _TRUNCATE);
350 maya 3227 }
351     else if (cv.PortType == IdSerial) {
352     strncpy_s(buf2,sizeof(buf2),buf,_TRUNCATE);
353     _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%sCOM%d", buf2, ts.ComPort);
354     }
355     }
356     break;
357 maya 3473 case 'p':
358     if (cv.Open) {
359     if (cv.PortType == IdTCPIP) {
360     char port[6];
361     _snprintf_s(port, sizeof(port), _TRUNCATE, "%d", ts.TCPPort);
362     strncat_s(buf,sizeof(buf),port,_TRUNCATE);
363     }
364     }
365     break;
366     default:
367 maya 3227 strncpy_s(buf2,sizeof(buf2),p,2);
368     strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
369     }
370     p++;
371     }
372     else {
373     strncpy_s(buf2,sizeof(buf2),p,1);
374     strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
375     }
376     p++;
377     }
378     strncpy_s(c, destlen, buf, _TRUNCATE);
379     }
380    
381     void FixLogOption()
382     {
383 doda 3887 if (ts.LogBinary) {
384 maya 3227 ts.LogTypePlainText = false;
385     ts.LogTimestamp = false;
386     }
387     }
388    
389 yutakapon 5206
390     // �X���b�h���I�����t�@�C�����N���[�Y
391     static void CloseFileSync(PFileVar ptr)
392     {
393     if (!ptr->FileOpen)
394     return;
395    
396     if (ptr->LogThread != (HANDLE)-1) {
397     // �X���b�h���I������
398     PostThreadMessage(ptr->LogThreadId, WM_QUIT, 0, 0);
399     WaitForSingleObject(ptr->LogThread, INFINITE);
400     CloseHandle(ptr->LogThread);
401     ptr->LogThread = (HANDLE)-1;
402     }
403 maya 5273 #ifdef FileVarWin16
404 yutakapon 5206 _lclose(ptr->FileHandle);
405 maya 5273 #else
406     CloseHandle((HANDLE)ptr->FileHandle);
407     #endif
408 yutakapon 5206 }
409    
410     // �x�����������p�X���b�h
411 doda 6435 static unsigned _stdcall DeferredLogWriteThread(void *arg)
412 yutakapon 5206 {
413     MSG msg;
414     PFileVar fv = (PFileVar)arg;
415     PCHAR buf;
416     DWORD buflen;
417 maya 5273 DWORD wrote;
418 yutakapon 5206
419     PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
420    
421     while (GetMessage(&msg, NULL, 0, 0) > 0) {
422     switch (msg.message) {
423     case WM_DPC_LOGTHREAD_SEND:
424     buf = (PCHAR)msg.wParam;
425     buflen = (DWORD)msg.lParam;
426 maya 5273 #ifdef FileVarWin16
427 yutakapon 5206 _lwrite(fv->FileHandle, buf, buflen );
428 maya 5273 #else
429     WriteFile((HANDLE)LogVar->FileHandle, buf, buflen, &wrote, NULL);
430     #endif
431 yutakapon 5206 free(buf); // ����������������
432     break;
433    
434     case WM_QUIT:
435     goto end;
436     break;
437     }
438     }
439    
440     end:
441     _endthreadex(0);
442     return (0);
443     }
444    
445    
446 maya 3227 extern "C" {
447     BOOL LogStart()
448     {
449     LONG Option;
450     char *logdir;
451 yutakapon 5206 unsigned tid;
452 yutakapon 5392 DWORD ofs, size, written_size;
453     char buf[512];
454 yutakapon 5395 const char *crlf = "\r\n";
455     DWORD crlf_len = 2;
456 maya 3227
457     if ((FileLog) || (BinLog)) return FALSE;
458    
459     if (! LoadTTFILE()) return FALSE;
460     if (! NewFileVar(&LogVar))
461     {
462     FreeTTFILE();
463     return FALSE;
464     }
465     LogVar->OpId = OpLog;
466    
467     if (strlen(ts.LogDefaultPath) > 0) {
468     logdir = ts.LogDefaultPath;
469     }
470     else if (strlen(ts.FileDir) > 0) {
471     logdir = ts.FileDir;
472     }
473     else {
474     logdir = ts.HomeDir;
475     }
476    
477     if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0)
478     {
479     // LOWORD
480     // 0x0001 = Binary
481     // HIWORD
482     // 0x0001 = Append
483     // 0x1000 = plain text (2005.2.20 yutaka)
484     // 0x2000 = timestamp (2006.7.23 maya)
485     // 0x4000 = hide file transfer dialog (2008.1.30 maya)
486 maya 5446 // 0x8000 = Include screen buffer (2013.9.29 yutaka)
487 maya 3227 // teraterm.ini�����������������f�t�H���g�I�v�V�������������B(2005.5.7 yutaka)
488 doda 3887 Option = MAKELONG(ts.LogBinary,
489 maya 3227 ts.Append |
490     (0x1000 * ts.LogTypePlainText) |
491     (0x2000 * ts.LogTimestamp) |
492 yutakapon 5392 (0x4000 * ts.LogHideDialog) |
493 doda 6435 (0x8000 * ts.LogAllBuffIncludedInFirst)
494     );
495 maya 3227
496     // ���O���f�t�H���g�t�@�C���������� (2006.8.28 maya)
497     strncat_s(LogVar->FullName, sizeof(LogVar->FullName), ts.LogDefaultName, _TRUNCATE);
498    
499     ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
500    
501     // &h ���z�X�g�����u�� (2007.5.14)
502     ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
503    
504     strncpy_s(LogVar->LogDefaultPath, sizeof(LogVar->LogDefaultPath), ts.LogDefaultPath, _TRUNCATE);
505     if (! (*GetTransFname)(LogVar, logdir, GTF_LOG, &Option))
506     {
507     FreeFileVar(&LogVar);
508     FreeTTFILE();
509     return FALSE;
510     }
511 doda 3887 ts.LogBinary = LOWORD(Option);
512 maya 3227 ts.Append = HIWORD(Option);
513    
514     if (ts.Append & 0x1000) {
515     ts.LogTypePlainText = 1;
516     } else {
517     ts.LogTypePlainText = 0;
518     }
519    
520     if (ts.Append & 0x2000) {
521     ts.LogTimestamp = 1;
522     }
523     else {
524     ts.LogTimestamp = 0;
525     }
526    
527     if (ts.Append & 0x4000) {
528     ts.LogHideDialog = 1;
529     }
530     else {
531     ts.LogHideDialog = 0;
532     }
533    
534 yutakapon 5392 if (ts.Append & 0x8000) {
535     ts.LogAllBuffIncludedInFirst = 1;
536     }
537     else {
538     ts.LogAllBuffIncludedInFirst = 0;
539     }
540    
541 maya 3227 ts.Append &= 0x1; // 1bit���}�X�N����
542    
543     }
544     else {
545     // LogVar->DirLen = 0 ��������������
546     // �t���p�X�E�����p�X������ LogVar->FullName �������������K�v������
547     char FileName[MAX_PATH];
548    
549     // �t���p�X��
550     strncpy_s(FileName, sizeof(FileName), LogVar->FullName, _TRUNCATE);
551     ConvFName(logdir,FileName,sizeof(FileName),"",LogVar->FullName,sizeof(LogVar->FullName));
552    
553     ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
554    
555     // &h ���z�X�g�����u�� (2007.5.14)
556     ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
557     (*SetFileVar)(LogVar);
558    
559     FixLogOption();
560     }
561    
562 doda 3887 if (ts.LogBinary > 0)
563 maya 3227 {
564     BinLog = TRUE;
565     FileLog = FALSE;
566     if (! CreateBinBuf())
567     {
568     FileTransEnd(OpLog);
569     return FALSE;
570     }
571     }
572     else {
573     BinLog = FALSE;
574     FileLog = TRUE;
575     if (! CreateLogBuf())
576     {
577     FileTransEnd(OpLog);
578     return FALSE;
579     }
580     }
581     cv.LStart = cv.LogPtr;
582     cv.LCount = 0;
583     if (ts.LogHideDialog)
584     LogVar->HideDialog = 1;
585    
586     HelpId = HlpFileLog;
587     /* 2007.05.24 Gentaro */
588     eLineEnd = Line_LineHead;
589    
590     if (ts.Append > 0)
591     {
592 maya 5189 int dwShareMode = FILE_SHARE_READ;
593 maya 5178 if (!ts.LogLockExclusive) {
594     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
595 maya 4786 }
596     LogVar->FileHandle = (int)CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
597 maya 4328 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
598 maya 3227 if (LogVar->FileHandle>0){
599 maya 5273 #ifdef FileVarWin16
600 maya 3227 _llseek(LogVar->FileHandle,0,2);
601 maya 5273 #else
602     SetFilePointer((HANDLE)LogVar->FileHandle, 0, NULL, FILE_END);
603     #endif
604 maya 3227 /* 2007.05.24 Gentaro
605     If log file already exists,
606     a newline is inserted before the first timestamp.
607     */
608     eLineEnd = Line_FileHead;
609     }
610     }
611 maya 4328 else {
612 maya 5189 int dwShareMode = FILE_SHARE_READ;
613 maya 5178 if (!ts.LogLockExclusive) {
614     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
615 maya 4786 }
616     LogVar->FileHandle = (int)CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
617 maya 4328 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
618     }
619 maya 3227 LogVar->FileOpen = (LogVar->FileHandle>0);
620     if (! LogVar->FileOpen)
621     {
622     char msg[128];
623    
624     // �t�@�C���I�[�v���G���[�������b�Z�[�W�\�������������B(2008.7.9 yutaka)
625     if (LogVar->NoMsg == FALSE) {
626     _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Can not create a `%s' file. (%d)", LogVar->FullName, GetLastError());
627     MessageBox(NULL, msg, "Tera Term: File open error", MB_OK | MB_ICONERROR);
628     }
629    
630     FileTransEnd(OpLog);
631     return FALSE;
632     }
633     LogVar->ByteCount = 0;
634    
635 yutakapon 5171 // Log rotate configuration
636     LogVar->RotateMode = ts.LogRotate;
637     LogVar->RotateSize = ts.LogRotateSize;
638     LogVar->RotateStep = ts.LogRotateStep;
639 yutakapon 5162
640 yutakapon 6365 // Log rotate���L���������A�����t�@�C���T�C�Y�����������B
641     // �������t�@�C�������������T�C�Y�����[�e�[�g�������������C���B
642     // (2016.4.9 yutaka)
643     if (LogVar->RotateMode != ROTATE_NONE) {
644     size = GetFileSize((HANDLE)LogVar->FileHandle, NULL);
645     if (size != -1)
646     LogVar->ByteCount = size;
647     }
648    
649 maya 3227 if (! OpenFTDlg(LogVar)) {
650     FileTransEnd(OpLog);
651     return FALSE;
652     }
653    
654 yutakapon 5206 // �x�����������p�X���b�h���N�����B
655     // (2013.4.19 yutaka)
656     LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
657     LogVar->LogThreadId = tid;
658    
659 yutakapon 5392 // �����o�b�t�@�������f�[�^�������������o���������A
660     // ���O�������J�n�����B
661     // (2013.9.29 yutaka)
662     if (ts.LogAllBuffIncludedInFirst) {
663     for (ofs = 0 ; ; ofs++ ) {
664 yutakapon 5395 // 1�����s�����������B���������������A�G�X�P�[�v�V�[�P���X�������������B
665 yutakapon 5392 size = BuffGetAnyLineData(ofs, buf, sizeof(buf));
666     if (size == -1)
667     break;
668 yutakapon 5395
669     #if 0
670     if (ts.DeferredLogWriteMode) { // �x����������
671     char *pbuf = (char *)malloc(size + 2);
672     memcpy(pbuf, buf, size);
673     pbuf[size] = '\r';
674     pbuf[size+1] = '\n';
675     Sleep(1); // �X���b�h�L���[�����������������A�R���e�L�X�g�X�C�b�`�������B
676     PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)pbuf, size + 2);
677     } else { // �������B�l�b�g���[�N�o�R�����x���B
678     #endif
679     WriteFile((HANDLE)LogVar->FileHandle, buf, size, &written_size, NULL);
680     WriteFile((HANDLE)LogVar->FileHandle, crlf, crlf_len, &written_size, NULL);
681     #if 0
682     }
683     #endif
684 yutakapon 5392 }
685     }
686    
687 maya 3227 return TRUE;
688     }
689     }
690    
691     void LogPut1(BYTE b)
692     {
693     LogLast = b;
694     cv.LogBuf[cv.LogPtr] = b;
695     cv.LogPtr++;
696     if (cv.LogPtr>=InBuffSize)
697     cv.LogPtr = cv.LogPtr-InBuffSize;
698    
699     if (FileLog)
700     {
701     if (cv.LCount>=InBuffSize)
702     {
703     cv.LCount = InBuffSize;
704     cv.LStart = cv.LogPtr;
705     }
706     else
707     cv.LCount++;
708     }
709     else
710     cv.LCount = 0;
711    
712     if (DDELog)
713     {
714     if (cv.DCount>=InBuffSize)
715     {
716     cv.DCount = InBuffSize;
717     cv.DStart = cv.LogPtr;
718     }
719     else
720     cv.DCount++;
721     }
722     else {
723     cv.DCount = 0;
724     // ���O���������}�N�����X�g�[���������������C���B
725     // ���O�����������x�}�N�����~�������A�o�b�t�@���C���f�b�N�X�������������������A
726     // ���x�}�N�������������������f�[�^�������������������B
727     // �}�N�������~���������������C���f�b�N�X�����������������������B
728     // (2006.12.26 yutaka)
729     cv.DStart = cv.LogPtr;
730     }
731     }
732    
733     void Log1Byte(BYTE b)
734     {
735     if (b==0x0d)
736     {
737     LogLast = b;
738     return;
739     }
740     if ((b==0x0a) && (LogLast==0x0d))
741     LogPut1(0x0d);
742     LogPut1(b);
743     }
744    
745     static BOOL Get1(PCHAR Buf, int *Start, int *Count, PBYTE b)
746     {
747     if (*Count<=0) return FALSE;
748     *b = Buf[*Start];
749     (*Start)++;
750     if (*Start>=InBuffSize)
751     *Start = *Start-InBuffSize;
752     (*Count)--;
753     return TRUE;
754     }
755    
756    
757    
758     static CRITICAL_SECTION g_filelog_lock; /* ���b�N�p���� */
759    
760     void logfile_lock_initialize(void)
761     {
762     InitializeCriticalSection(&g_filelog_lock);
763     }
764    
765     static inline void logfile_lock(void)
766     {
767     EnterCriticalSection(&g_filelog_lock);
768     }
769    
770     static inline void logfile_unlock(void)
771     {
772     LeaveCriticalSection(&g_filelog_lock);
773     }
774    
775     // �R�����g�����O����������
776     void CommentLogToFile(char *buf, int size)
777     {
778     DWORD wrote;
779    
780     if (LogVar == NULL || !LogVar->FileOpen) {
781     char uimsg[MAX_UIMSG];
782     get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
783     get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
784     "It is not opened by the log file yet.", ts.UILanguageFile);
785     ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
786     return;
787     }
788    
789     logfile_lock();
790     WriteFile((HANDLE)LogVar->FileHandle, buf, size, &wrote, NULL);
791     WriteFile((HANDLE)LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
792     /* Set Line End Flag
793     2007.05.24 Gentaro
794     */
795     eLineEnd = Line_LineHead;
796     logfile_unlock();
797     }
798    
799 yutakapon 5162 // ���O�����[�e�[�g�����B
800     // (2013.3.21 yutaka)
801     static void LogRotate(void)
802     {
803 yutakapon 5165 int loopmax = 10000; // XXX
804 yutakapon 5162 char filename[1024];
805 yutakapon 5165 char newfile[1024], oldfile[1024];
806     int i, k;
807 maya 5189 int dwShareMode = FILE_SHARE_READ;
808 yutakapon 5206 unsigned tid;
809 yutakapon 5162
810     if (! LogVar->FileOpen) return;
811    
812     if (LogVar->RotateMode == ROTATE_NONE)
813     return;
814    
815     if (LogVar->RotateMode == ROTATE_SIZE) {
816 doda 6435 if (LogVar->ByteCount <= LogVar->RotateSize)
817 yutakapon 5162 return;
818     //OutputDebugPrintf("%s: mode %d size %ld\n", __FUNCTION__, LogVar->RotateMode, LogVar->ByteCount);
819     } else {
820     return;
821     }
822    
823     logfile_lock();
824     // ���O�T�C�Y���������������B
825     LogVar->ByteCount = 0;
826    
827     // �������������t�@�C�����N���[�Y�����A�������t�@�C�����I�[�v�������B
828 yutakapon 5206 CloseFileSync(LogVar);
829     //_lclose(LogVar->FileHandle);
830 yutakapon 5162
831 yutakapon 5165 // �������[�e�[�V�������X�e�b�v�����w����������
832     if (LogVar->RotateStep > 0)
833     loopmax = LogVar->RotateStep;
834    
835     for (i = 1 ; i <= loopmax ; i++) {
836 yutakapon 5162 _snprintf_s(filename, sizeof(filename), _TRUNCATE, "%s.%d", LogVar->FullName, i);
837     if (_access_s(filename, 0) != 0)
838     break;
839     }
840 yutakapon 5165 if (i > loopmax) {
841     // �������������������������A�������t�@�C�������p�������B
842     i = loopmax;
843 yutakapon 5162 }
844    
845     // ���t�@�C�������l�[���B
846 yutakapon 5165 for (k = i-1 ; k >= 0 ; k--) {
847     if (k == 0)
848     strncpy_s(oldfile, sizeof(oldfile), LogVar->FullName, _TRUNCATE);
849     else
850     _snprintf_s(oldfile, sizeof(oldfile), _TRUNCATE, "%s.%d", LogVar->FullName, k);
851     _snprintf_s(newfile, sizeof(newfile), _TRUNCATE, "%s.%d", LogVar->FullName, k+1);
852     remove(newfile);
853     if (rename(oldfile, newfile) != 0) {
854     OutputDebugPrintf("%s: rename %d\n", __FUNCTION__, errno);
855     }
856     }
857 yutakapon 5162
858     // ���I�[�v��
859 maya 5178 if (!ts.LogLockExclusive) {
860     dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
861 yutakapon 5162 }
862     LogVar->FileHandle = (int)CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
863     CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
864    
865 yutakapon 5206 // �x�����������p�X���b�h���N�����B
866     // (2013.4.19 yutaka)
867     LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
868     LogVar->LogThreadId = tid;
869    
870 yutakapon 5162 logfile_unlock();
871    
872     }
873    
874 maya 3227 void LogToFile()
875     {
876     PCHAR Buf;
877     int Start, Count;
878     BYTE b;
879 yutakapon 5206 PCHAR WriteBuf;
880     DWORD WriteBufMax, WriteBufLen;
881     CHAR tmp[128];
882 maya 5273 DWORD wrote;
883 maya 3227
884     if (! LogVar->FileOpen) return;
885     if (FileLog)
886     {
887     Buf = cv.LogBuf;
888     Start = cv.LStart;
889     Count = cv.LCount;
890     }
891     else if (BinLog)
892     {
893     Buf = cv.BinBuf;
894     Start = cv.BStart;
895     Count = cv.BCount;
896     }
897     else
898     return;
899    
900     if (Buf==NULL) return;
901     if (Count==0) return;
902    
903     // ���b�N������(2004.8.6 yutaka)
904     logfile_lock();
905    
906 yutakapon 5206 if (ts.DeferredLogWriteMode) {
907     WriteBufMax = 8192;
908     WriteBufLen = 0;
909     WriteBuf = (PCHAR)malloc(WriteBufMax);
910     while (Get1(Buf,&Start,&Count,&b)) {
911     if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
912     {
913     tmp[0] = 0;
914     if ( ts.LogTimestamp && eLineEnd ) {
915     char *strtime = mctimelocal();
916     /* 2007.05.24 Gentaro */
917     if( eLineEnd == Line_FileHead ){
918     strncat_s(tmp, sizeof(tmp), "\r\n", _TRUNCATE);
919     }
920     strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE);
921     strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE);
922     strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE);
923     }
924 doda 6435
925 yutakapon 5206 /* 2007.05.24 Gentaro */
926     if( b == 0x0a ){
927     eLineEnd = Line_LineHead; /* set endmark*/
928     }
929     else {
930     eLineEnd = Line_Other; /* clear endmark*/
931     }
932    
933     if (WriteBufLen >= (WriteBufMax*4/5)) {
934     WriteBufMax *= 2;
935     WriteBuf = (PCHAR)realloc(WriteBuf, WriteBufMax);
936     }
937     memcpy(&WriteBuf[WriteBufLen], tmp, strlen(tmp));
938     WriteBufLen += strlen(tmp);
939     WriteBuf[WriteBufLen++] = b;
940    
941     (LogVar->ByteCount)++;
942     }
943     }
944    
945     PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)WriteBuf, WriteBufLen);
946    
947     } else {
948    
949     while (Get1(Buf,&Start,&Count,&b))
950 maya 3227 {
951 yutakapon 5206 if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
952     {
953     // �����������o��(2006.7.23 maya)
954     // ���t�t�H�[�}�b�g�����{�����������E�W�������X���� (2006.7.23 yutaka)
955     /* 2007.05.24 Gentaro */
956     // �~���b���\���������������X (2009.5.23 maya)
957     if ( ts.LogTimestamp && eLineEnd ) {
958     #if 1
959     #if 0
960     SYSTEMTIME LocalTime;
961     GetLocalTime(&LocalTime);
962     char strtime[27];
963 maya 3227
964 yutakapon 5206 // format time
965     sprintf(strtime, "[%04d/%02d/%02d %02d:%02d:%02d.%03d] ",
966     LocalTime.wYear, LocalTime.wMonth,LocalTime.wDay,
967     LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond,
968     LocalTime.wMilliseconds);
969     #else
970     char *strtime = mctimelocal();
971     #endif
972     #else
973     time_t tick = time(NULL);
974 doda 6435 char *strtime = ctime(&tick);
975 yutakapon 5206 #endif
976     /* 2007.05.24 Gentaro */
977     if( eLineEnd == Line_FileHead ){
978 maya 5273 #ifdef FileVarWin16
979 yutakapon 5206 _lwrite(LogVar->FileHandle,"\r\n",2);
980 maya 5273 #else
981     WriteFile((HANDLE)LogVar->FileHandle, "\r\n", 2, &wrote, NULL);
982     #endif
983 yutakapon 5206 }
984 maya 5273 #ifdef FileVarWin16
985 yutakapon 5206 _lwrite(LogVar->FileHandle,"[",1);
986     _lwrite(LogVar->FileHandle, strtime, strlen(strtime));
987     _lwrite(LogVar->FileHandle,"] ",2);
988 maya 5273 #else
989     WriteFile((HANDLE)LogVar->FileHandle, "[", 1, &wrote, NULL);
990     WriteFile((HANDLE)LogVar->FileHandle, strtime, strlen(strtime), &wrote, NULL);
991     WriteFile((HANDLE)LogVar->FileHandle, "] ", 2, &wrote, NULL);
992     #endif
993 yutakapon 5206 }
994 doda 6435
995 maya 3227 /* 2007.05.24 Gentaro */
996 yutakapon 5206 if( b == 0x0a ){
997     eLineEnd = Line_LineHead; /* set endmark*/
998 maya 3227 }
999 yutakapon 5206 else {
1000     eLineEnd = Line_Other; /* clear endmark*/
1001     }
1002    
1003 maya 5273 #ifdef FileVarWin16
1004 yutakapon 5206 _lwrite(LogVar->FileHandle,(PCHAR)&b,1);
1005 maya 5273 #else
1006     WriteFile((HANDLE)LogVar->FileHandle, (PCHAR)&b, 1, &wrote, NULL);
1007     #endif
1008 yutakapon 5206 (LogVar->ByteCount)++;
1009 maya 3227 }
1010 yutakapon 5206 }
1011 maya 3227
1012     }
1013    
1014     logfile_unlock();
1015    
1016     if (FileLog)
1017     {
1018     cv.LStart = Start;
1019     cv.LCount = Count;
1020     }
1021     else {
1022     cv.BStart = Start;
1023     cv.BCount = Count;
1024     }
1025     if (((cv.FilePause & OpLog) !=0) || cv.ProtoFlag) return;
1026     if (FLogDlg!=NULL)
1027     FLogDlg->RefreshNum();
1028 yutakapon 5162
1029     // ���O�E���[�e�[�g
1030     LogRotate();
1031    
1032 maya 3227 }
1033    
1034     BOOL CreateLogBuf()
1035     {
1036     if (cv.HLogBuf==NULL)
1037     {
1038     cv.HLogBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1039     cv.LogBuf = NULL;
1040     cv.LogPtr = 0;
1041     cv.LStart = 0;
1042     cv.LCount = 0;
1043     cv.DStart = 0;
1044     cv.DCount = 0;
1045     }
1046     return (cv.HLogBuf!=NULL);
1047     }
1048    
1049     void FreeLogBuf()
1050     {
1051     if ((cv.HLogBuf==NULL) || FileLog || DDELog)
1052     return;
1053     if (cv.LogBuf!=NULL)
1054     GlobalUnlock(cv.HLogBuf);
1055     GlobalFree(cv.HLogBuf);
1056     cv.HLogBuf = NULL;
1057     cv.LogBuf = NULL;
1058     cv.LogPtr = 0;
1059     cv.LStart = 0;
1060     cv.LCount = 0;
1061     cv.DStart = 0;
1062     cv.DCount = 0;
1063     }
1064    
1065     BOOL CreateBinBuf()
1066     {
1067     if (cv.HBinBuf==NULL)
1068     {
1069     cv.HBinBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1070     cv.BinBuf = NULL;
1071     cv.BinPtr = 0;
1072     cv.BStart = 0;
1073     cv.BCount = 0;
1074     }
1075     return (cv.HBinBuf!=NULL);
1076     }
1077    
1078     void FreeBinBuf()
1079     {
1080     if ((cv.HBinBuf==NULL) || BinLog)
1081     return;
1082     if (cv.BinBuf!=NULL)
1083     GlobalUnlock(cv.HBinBuf);
1084     GlobalFree(cv.HBinBuf);
1085     cv.HBinBuf = NULL;
1086     cv.BinBuf = NULL;
1087     cv.BinPtr = 0;
1088     cv.BStart = 0;
1089     cv.BCount = 0;
1090     }
1091    
1092     extern "C" {
1093     void FileSendStart()
1094     {
1095     LONG Option;
1096    
1097     if (! cv.Ready || FSend) return;
1098     if (cv.ProtoFlag)
1099     {
1100     FreeFileVar(&SendVar);
1101     return;
1102     }
1103    
1104 doda 6435 if (! LoadTTFILE())
1105 maya 3227 return;
1106     if (! NewFileVar(&SendVar))
1107     {
1108     FreeTTFILE();
1109     return;
1110     }
1111     SendVar->OpId = OpSendFile;
1112    
1113     FSend = TRUE;
1114    
1115     if (strlen(&(SendVar->FullName[SendVar->DirLen]))==0)
1116     {
1117     Option = MAKELONG(ts.TransBin,0);
1118     SendVar->FullName[0] = 0;
1119     if (! (*GetTransFname)(SendVar, ts.FileDir, GTF_SEND, &Option))
1120     {
1121     FileTransEnd(OpSendFile);
1122     return;
1123     }
1124     ts.TransBin = LOWORD(Option);
1125     }
1126     else
1127     (*SetFileVar)(SendVar);
1128    
1129 maya 5281 #ifdef FileVarWin16
1130 maya 3227 SendVar->FileHandle = _lopen(SendVar->FullName,OF_READ);
1131 maya 5281 #else
1132     SendVar->FileHandle = (int)CreateFile(SendVar->FullName, GENERIC_READ, FILE_SHARE_READ, NULL,
1133 maya 6071 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1134 maya 5281 #endif
1135 maya 3227 SendVar->FileOpen = (SendVar->FileHandle>0);
1136     if (! SendVar->FileOpen)
1137     {
1138     FileTransEnd(OpSendFile);
1139     return;
1140     }
1141     SendVar->ByteCount = 0;
1142     SendVar->FileSize = GetFSize(SendVar->FullName);
1143    
1144     TalkStatus = IdTalkFile;
1145     FileRetrySend = FALSE;
1146     FileRetryEcho = FALSE;
1147     FileCRSend = FALSE;
1148 doda 3904 FileReadEOF = FALSE;
1149 maya 6071 FileSendHandler.pos = 0;
1150     FileSendHandler.end = 0;
1151     FileDlgRefresh = 0;
1152 maya 3227
1153 doda 3904 if (BracketedPasteMode()) {
1154     FileBracketMode = FS_BRACKET_START;
1155     FileBracketPtr = 0;
1156     BinaryMode = TRUE;
1157     }
1158     else {
1159     FileBracketMode = FS_BRACKET_NONE;
1160     BinaryMode = ts.TransBin;
1161     }
1162    
1163 maya 3227 if (! OpenFTDlg(SendVar))
1164     FileTransEnd(OpSendFile);
1165     }
1166     }
1167    
1168     void FileTransEnd(WORD OpId)
1169     /* OpId = 0: close Log and FileSend
1170     OpLog: close Log
1171     OpSendFile: close FileSend */
1172     {
1173     if (((OpId==0) || (OpId==OpLog)) && (FileLog || BinLog))
1174     {
1175     FileLog = FALSE;
1176     BinLog = FALSE;
1177     if (FLogDlg!=NULL)
1178     {
1179     FLogDlg->DestroyWindow();
1180     FLogDlg = NULL;
1181 doda 6435 HWndLog = NULL; // steven add
1182 maya 3227 }
1183     FreeFileVar(&LogVar);
1184     FreeLogBuf();
1185     FreeBinBuf();
1186     FreeTTFILE();
1187     }
1188    
1189     if (((OpId==0) || (OpId==OpSendFile)) && FSend)
1190     {
1191     FSend = FALSE;
1192     TalkStatus = IdTalkKeyb;
1193     if (SendDlg!=NULL)
1194     {
1195     SendDlg->DestroyWindow();
1196     SendDlg = NULL;
1197     }
1198     FreeFileVar(&SendVar);
1199     FreeTTFILE();
1200     }
1201    
1202     EndDdeCmnd(0);
1203     }
1204    
1205     int FSOut1(BYTE b)
1206     {
1207 doda 3904 if (BinaryMode)
1208 maya 3227 return CommBinaryOut(&cv,(PCHAR)&b,1);
1209     else if ((b>=0x20) || (b==0x09) || (b==0x0A) || (b==0x0D))
1210     return CommTextOut(&cv,(PCHAR)&b,1);
1211     else
1212     return 1;
1213 doda 3861 }
1214 maya 3227
1215     int FSEcho1(BYTE b)
1216     {
1217 doda 3904 if (BinaryMode)
1218 maya 3227 return CommBinaryEcho(&cv,(PCHAR)&b,1);
1219     else
1220     return CommTextEcho(&cv,(PCHAR)&b,1);
1221     }
1222    
1223     extern "C" {
1224 maya 6071 // �������������������������g��
1225     // - BinaryMode == true
1226     // - FileBracketMode == false
1227     // - cv.TelFlag == false
1228     // - ts.LocalEcho == 0
1229 doda 6435 void FileSendBinayBoost()
1230 maya 6071 {
1231     WORD c, fc;
1232     LONG BCOld;
1233     DWORD read_bytes;
1234    
1235     if ((SendDlg == NULL) ||
1236     ((cv.FilePause & OpSendFile) != 0))
1237     return;
1238    
1239     BCOld = SendVar->ByteCount;
1240    
1241     if (FileRetrySend)
1242     {
1243     c = CommRawOut(&cv, &(FileSendHandler.buf[FileSendHandler.pos]),
1244     FileSendHandler.end - FileSendHandler.pos);
1245     FileSendHandler.pos += c;
1246     FileRetrySend = (FileSendHandler.end != FileSendHandler.pos);
1247     if (FileRetrySend)
1248     return;
1249     }
1250    
1251     do {
1252     if (FileSendHandler.pos == FileSendHandler.end) {
1253     #ifdef FileVarWin16
1254     fc = _lread(SendVar->FileHandle, &(FileSendHandler.buf[0]), sizeof(FileSendHandler.buf));
1255     #else
1256     ReadFile((HANDLE)SendVar->FileHandle, &(FileSendHandler.buf[0]), sizeof(FileSendHandler.buf), &read_bytes, NULL);
1257     fc = LOWORD(read_bytes);
1258     #endif
1259     FileSendHandler.pos = 0;
1260     FileSendHandler.end = fc;
1261     } else {
1262     fc = FileSendHandler.end - FileSendHandler.end;
1263     }
1264    
1265     if (fc != 0)
1266     {
1267     c = CommRawOut(&cv, &(FileSendHandler.buf[FileSendHandler.pos]),
1268     FileSendHandler.end - FileSendHandler.pos);
1269     FileSendHandler.pos += c;
1270     FileRetrySend = (FileSendHandler.end != FileSendHandler.pos);
1271     SendVar->ByteCount = SendVar->ByteCount + c;
1272     if (FileRetrySend)
1273     {
1274     if (SendVar->ByteCount != BCOld)
1275     SendDlg->RefreshNum();
1276     return;
1277     }
1278     }
1279     FileDlgRefresh = SendVar->ByteCount;
1280     SendDlg->RefreshNum();
1281     BCOld = SendVar->ByteCount;
1282     if (fc != 0)
1283     return;
1284     } while (fc != 0);
1285    
1286     FileTransEnd(OpSendFile);
1287     }
1288     }
1289    
1290     extern "C" {
1291 maya 3227 void FileSend()
1292     {
1293     WORD c, fc;
1294     LONG BCOld;
1295 maya 5281 DWORD read_bytes;
1296 maya 3227
1297 maya 6115 if (cv.PortType == IdSerial && ts.FileSendHighSpeedMode &&
1298 maya 6110 BinaryMode && !FileBracketMode && !cv.TelFlag &&
1299 maya 6079 (ts.LocalEcho == 0) && (ts.Baud >= 115200)) {
1300 maya 6071 return FileSendBinayBoost();
1301     }
1302    
1303 maya 3227 if ((SendDlg==NULL) ||
1304     ((cv.FilePause & OpSendFile) !=0))
1305     return;
1306    
1307     BCOld = SendVar->ByteCount;
1308    
1309     if (FileRetrySend)
1310     {
1311     FileRetryEcho = (ts.LocalEcho>0);
1312     c = FSOut1(FileByte);
1313     FileRetrySend = (c==0);
1314     if (FileRetrySend)
1315     return;
1316     }
1317    
1318     if (FileRetryEcho)
1319     {
1320     c = FSEcho1(FileByte);
1321     FileRetryEcho = (c==0);
1322     if (FileRetryEcho)
1323     return;
1324     }
1325    
1326     do {
1327 doda 3904 if (FileBracketMode == FS_BRACKET_START) {
1328     FileByte = BracketStartStr[FileBracketPtr++];
1329     fc = 1;
1330 maya 3227
1331 doda 3904 if (FileBracketPtr >= sizeof(BracketStartStr) - 1) {
1332     FileBracketMode = FS_BRACKET_END;
1333     FileBracketPtr = 0;
1334     BinaryMode = ts.TransBin;
1335     }
1336     }
1337     else if (! FileReadEOF) {
1338 maya 5281 #ifdef FileVarWin16
1339 maya 3227 fc = _lread(SendVar->FileHandle,&FileByte,1);
1340 maya 5281 #else
1341     ReadFile((HANDLE)SendVar->FileHandle, &FileByte, 1, &read_bytes, NULL);
1342     fc = LOWORD(read_bytes);
1343     #endif
1344 maya 3227 SendVar->ByteCount = SendVar->ByteCount + fc;
1345 doda 3904
1346     if (FileCRSend && (fc==1) && (FileByte==0x0A)) {
1347 maya 5281 #ifdef FileVarWin16
1348 doda 3904 fc = _lread(SendVar->FileHandle,&FileByte,1);
1349 maya 5281 #else
1350     ReadFile((HANDLE)SendVar->FileHandle, &FileByte, 1, &read_bytes, NULL);
1351     fc = LOWORD(read_bytes);
1352     #endif
1353 doda 3904 SendVar->ByteCount = SendVar->ByteCount + fc;
1354     }
1355 maya 3227 }
1356 doda 3904 else {
1357     fc = 0;
1358     }
1359 maya 3227
1360 doda 3904 if (fc == 0 && FileBracketMode == FS_BRACKET_END) {
1361     FileReadEOF = TRUE;
1362     FileByte = BracketEndStr[FileBracketPtr++];
1363     fc = 1;
1364     BinaryMode = TRUE;
1365    
1366     if (FileBracketPtr >= sizeof(BracketEndStr) - 1) {
1367     FileBracketMode = FS_BRACKET_NONE;
1368     FileBracketPtr = 0;
1369     }
1370     }
1371    
1372    
1373 maya 3227 if (fc!=0)
1374     {
1375     c = FSOut1(FileByte);
1376     FileCRSend = (ts.TransBin==0) && (FileByte==0x0D);
1377     FileRetrySend = (c==0);
1378     if (FileRetrySend)
1379     {
1380     if (SendVar->ByteCount != BCOld)
1381     SendDlg->RefreshNum();
1382     return;
1383     }
1384     if (ts.LocalEcho>0)
1385     {
1386     c = FSEcho1(FileByte);
1387     FileRetryEcho = (c==0);
1388     if (FileRetryEcho)
1389     return;
1390     }
1391     }
1392 doda 3904 if ((fc==0) || ((SendVar->ByteCount % 100 == 0) && (FileBracketPtr == 0))) {
1393 maya 3227 SendDlg->RefreshNum();
1394     BCOld = SendVar->ByteCount;
1395     if (fc!=0)
1396     return;
1397     }
1398     } while (fc!=0);
1399    
1400     FileTransEnd(OpSendFile);
1401     }
1402     }
1403    
1404     extern "C" {
1405     void FLogChangeButton(BOOL Pause)
1406     {
1407     if (FLogDlg!=NULL)
1408     FLogDlg->ChangeButton(Pause);
1409     }
1410     }
1411    
1412     extern "C" {
1413     void FLogRefreshNum()
1414     {
1415     if (FLogDlg!=NULL)
1416     FLogDlg->RefreshNum();
1417     }
1418     }
1419    
1420     BOOL OpenProtoDlg(PFileVar fv, int IdProto, int Mode, WORD Opt1, WORD Opt2)
1421     {
1422     int vsize;
1423     PProtoDlg pd;
1424     HWND Hpd;
1425     char uimsg[MAX_UIMSG];
1426    
1427     ProtoId = IdProto;
1428    
1429     switch (ProtoId) {
1430     case PROTO_KMT:
1431     vsize = sizeof(TKmtVar);
1432     break;
1433     case PROTO_XM:
1434     vsize = sizeof(TXVar);
1435     break;
1436     case PROTO_YM:
1437     vsize = sizeof(TYVar);
1438     break;
1439     case PROTO_ZM:
1440     vsize = sizeof(TZVar);
1441     break;
1442     case PROTO_BP:
1443     vsize = sizeof(TBPVar);
1444     break;
1445     case PROTO_QV:
1446     vsize = sizeof(TQVVar);
1447     break;
1448     }
1449     ProtoVar = (PCHAR)malloc(vsize);
1450     if (ProtoVar==NULL)
1451     return FALSE;
1452    
1453     switch (ProtoId) {
1454     case PROTO_KMT:
1455     ((PKmtVar)ProtoVar)->KmtMode = Mode;
1456     break;
1457     case PROTO_XM:
1458     ((PXVar)ProtoVar)->XMode = Mode;
1459     ((PXVar)ProtoVar)->XOpt = Opt1;
1460     ((PXVar)ProtoVar)->TextFlag = 1 - (Opt2 & 1);
1461     break;
1462 doda 6435 case PROTO_YM:
1463 maya 3227 ((PYVar)ProtoVar)->YMode = Mode;
1464 yutakapon 3819 ((PYVar)ProtoVar)->YOpt = Opt1;
1465 maya 3227 break;
1466     case PROTO_ZM:
1467     ((PZVar)ProtoVar)->BinFlag = (Opt1 & 1) != 0;
1468     ((PZVar)ProtoVar)->ZMode = Mode;
1469     break;
1470     case PROTO_BP:
1471     ((PBPVar)ProtoVar)->BPMode = Mode;
1472     break;
1473     case PROTO_QV:
1474     ((PQVVar)ProtoVar)->QVMode = Mode;
1475     break;
1476     }
1477    
1478     pd = new CProtoDlg();
1479     if (pd==NULL)
1480     {
1481     free(ProtoVar);
1482     ProtoVar = NULL;
1483     return FALSE;
1484     }
1485     pd->Create(fv,&ts);
1486    
1487     Hpd=pd->GetSafeHwnd();
1488    
1489     GetDlgItemText(Hpd, IDC_PROT_FILENAME, uimsg, sizeof(uimsg));
1490     get_lang_msg("DLG_PROT_FIELNAME", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1491     SetDlgItemText(Hpd, IDC_PROT_FILENAME, ts.UIMsg);
1492     GetDlgItemText(Hpd, IDC_PROT_PROT, uimsg, sizeof(uimsg));
1493     get_lang_msg("DLG_PROT_PROTO", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1494     SetDlgItemText(Hpd, IDC_PROT_PROT, ts.UIMsg);
1495     GetDlgItemText(Hpd, IDC_PROT_PACKET, uimsg, sizeof(uimsg));
1496     get_lang_msg("DLG_PROT_PACKET", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1497     SetDlgItemText(Hpd, IDC_PROT_PACKET, ts.UIMsg);
1498     GetDlgItemText(Hpd, IDC_PROT_TRANS, uimsg, sizeof(uimsg));
1499     get_lang_msg("DLG_PROT_TRANS", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1500     SetDlgItemText(Hpd, IDC_PROT_TRANS, ts.UIMsg);
1501 doda 4461 GetDlgItemText(Hpd, IDC_PROT_ELAPSED, uimsg, sizeof(uimsg));
1502     get_lang_msg("DLG_PROT_ELAPSED", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1503     SetDlgItemText(Hpd, IDC_PROT_ELAPSED, ts.UIMsg);
1504 maya 3227 GetDlgItemText(Hpd, IDCANCEL, uimsg, sizeof(uimsg));
1505     get_lang_msg("BTN_CANCEL", ts.UIMsg, sizeof(ts.UIMsg), uimsg, ts.UILanguageFile);
1506     SetDlgItemText(Hpd, IDCANCEL, ts.UIMsg);
1507    
1508     (*ProtoInit)(ProtoId,FileVar,ProtoVar,&cv,&ts);
1509    
1510     PtDlg = pd;
1511     return TRUE;
1512     }
1513    
1514     extern "C" {
1515     void CloseProtoDlg()
1516     {
1517     if (PtDlg!=NULL)
1518     {
1519     PtDlg->DestroyWindow();
1520     PtDlg = NULL;
1521    
1522     ::KillTimer(FileVar->HMainWin,IdProtoTimer);
1523     if ((ProtoId==PROTO_QV) &&
1524     (((PQVVar)ProtoVar)->QVMode==IdQVSend))
1525     CommTextOut(&cv,"\015",1);
1526     if (FileVar->LogFlag)
1527 doda 6435 _lclose(FileVar->LogFile);
1528 maya 3227 FileVar->LogFile = 0;
1529     if (ProtoVar!=NULL)
1530     {
1531     free(ProtoVar);
1532     ProtoVar = NULL;
1533     }
1534     }
1535     }
1536     }
1537    
1538     BOOL ProtoStart()
1539     {
1540     if (cv.ProtoFlag)
1541     return FALSE;
1542     if (FSend)
1543     {
1544     FreeFileVar(&FileVar);
1545     return FALSE;
1546     }
1547    
1548     if (! LoadTTFILE())
1549     return FALSE;
1550     NewFileVar(&FileVar);
1551    
1552     if (FileVar==NULL)
1553     {
1554     FreeTTFILE();
1555     return FALSE;
1556     }
1557     cv.ProtoFlag = TRUE;
1558     return TRUE;
1559     }
1560    
1561     void ProtoEnd()
1562     {
1563     if (! cv.ProtoFlag)
1564     return;
1565     cv.ProtoFlag = FALSE;
1566    
1567     /* Enable transmit delay (serial port) */
1568     cv.DelayFlag = TRUE;
1569     TalkStatus = IdTalkKeyb;
1570    
1571     CloseProtoDlg();
1572    
1573     if ((FileVar!=NULL) && FileVar->Success)
1574     EndDdeCmnd(1);
1575     else
1576     EndDdeCmnd(0);
1577    
1578     FreeTTFILE();
1579     FreeFileVar(&FileVar);
1580     }
1581    
1582     extern "C" {
1583     int ProtoDlgParse()
1584     {
1585     int P;
1586    
1587     P = ActiveWin;
1588     if (PtDlg==NULL)
1589     return P;
1590    
1591     if ((*ProtoParse)(ProtoId,FileVar,ProtoVar,&cv))
1592     P = 0; /* continue */
1593     else {
1594     CommSend(&cv);
1595     ProtoEnd();
1596     }
1597     return P;
1598     }
1599     }
1600    
1601     extern "C" {
1602     void ProtoDlgTimeOut()
1603     {
1604     if (PtDlg!=NULL)
1605     (*ProtoTimeOutProc)(ProtoId,FileVar,ProtoVar,&cv);
1606     }
1607     }
1608    
1609     extern "C" {
1610     void ProtoDlgCancel()
1611     {
1612     if ((PtDlg!=NULL) &&
1613     (*ProtoCancel)(ProtoId,FileVar,ProtoVar,&cv))
1614     ProtoEnd();
1615     }
1616     }
1617    
1618     extern "C" {
1619     void KermitStart(int mode)
1620     {
1621     WORD w;
1622    
1623     if (! ProtoStart())
1624     return;
1625    
1626     switch (mode) {
1627     case IdKmtSend:
1628     FileVar->OpId = OpKmtSend;
1629     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1630     {
1631     if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_KERMIT,&w) ||
1632     (FileVar->NumFname==0))
1633     {
1634     ProtoEnd();
1635     return;
1636     }
1637     }
1638     else
1639     (*SetFileVar)(FileVar);
1640     break;
1641     case IdKmtReceive:
1642     FileVar->OpId = OpKmtRcv;
1643     break;
1644     case IdKmtGet:
1645     FileVar->OpId = OpKmtSend;
1646     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1647     {
1648 doda 6435 if (! (*GetGetFname)(FileVar->HMainWin,FileVar) ||
1649 maya 3227 (strlen(FileVar->FullName)==0))
1650     {
1651     ProtoEnd();
1652     return;
1653     }
1654     }
1655     else
1656     (*SetFileVar)(FileVar);
1657     break;
1658     case IdKmtFinish:
1659     FileVar->OpId = OpKmtFin;
1660     break;
1661     default:
1662     ProtoEnd();
1663     return;
1664     }
1665     TalkStatus = IdTalkQuiet;
1666    
1667     /* disable transmit delay (serial port) */
1668     cv.DelayFlag = FALSE;
1669    
1670     if (! OpenProtoDlg(FileVar,PROTO_KMT,mode,0,0))
1671     ProtoEnd();
1672     }
1673     }
1674    
1675     extern "C" {
1676     void XMODEMStart(int mode)
1677     {
1678     LONG Option;
1679 doda 6328 int tmp;
1680 maya 3227
1681     if (! ProtoStart())
1682     return;
1683    
1684     if (mode==IdXReceive)
1685     FileVar->OpId = OpXRcv;
1686     else
1687     FileVar->OpId = OpXSend;
1688    
1689     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1690     {
1691     Option = MAKELONG(ts.XmodemBin,ts.XmodemOpt);
1692     if (! (*GetXFname)(FileVar->HMainWin,
1693     mode==IdXReceive,&Option,FileVar,ts.FileDir))
1694     {
1695     ProtoEnd();
1696     return;
1697     }
1698 doda 6328 tmp = HIWORD(Option);
1699     if (mode == IdXReceive) {
1700     if (IsXoptCRC(tmp)) {
1701     if (IsXopt1k(ts.XmodemOpt)) {
1702     ts.XmodemOpt = Xopt1kCRC;
1703     }
1704     else {
1705     ts.XmodemOpt = XoptCRC;
1706     }
1707     }
1708     else {
1709     if (IsXopt1k(ts.XmodemOpt)) {
1710     ts.XmodemOpt = Xopt1kCksum;
1711     }
1712     else {
1713     ts.XmodemOpt = XoptCheck;
1714     }
1715     }
1716     ts.XmodemBin = LOWORD(Option);
1717     }
1718     else {
1719     if (IsXopt1k(tmp)) {
1720     if (IsXoptCRC(ts.XmodemOpt)) {
1721     ts.XmodemOpt = Xopt1kCRC;
1722     }
1723     else {
1724     ts.XmodemOpt = Xopt1kCksum;
1725     }
1726     }
1727     else {
1728     if (IsXoptCRC(ts.XmodemOpt)) {
1729     ts.XmodemOpt = XoptCRC;
1730     }
1731     else {
1732     ts.XmodemOpt = XoptCheck;
1733     }
1734     }
1735     }
1736 maya 3227 }
1737     else
1738     (*SetFileVar)(FileVar);
1739    
1740     if (mode==IdXReceive)
1741     FileVar->FileHandle = _lcreat(FileVar->FullName,0);
1742     else
1743     FileVar->FileHandle = _lopen(FileVar->FullName,OF_READ);
1744    
1745     FileVar->FileOpen = FileVar->FileHandle>0;
1746     if (! FileVar->FileOpen)
1747     {
1748     ProtoEnd();
1749     return;
1750     }
1751     TalkStatus = IdTalkQuiet;
1752    
1753     /* disable transmit delay (serial port) */
1754     cv.DelayFlag = FALSE;
1755    
1756     if (! OpenProtoDlg(FileVar,PROTO_XM,mode,
1757     ts.XmodemOpt,ts.XmodemBin))
1758     ProtoEnd();
1759     }
1760     }
1761    
1762     extern "C" {
1763     void YMODEMStart(int mode)
1764     {
1765     WORD Opt;
1766    
1767     if (! ProtoStart())
1768     return;
1769    
1770     if (mode==IdYSend)
1771     {
1772 yutakapon 3819 // �t�@�C���]�������I�v�V������"Yopt1K"�����������B
1773     // TODO: "Yopt1K", "YoptG", "YoptSingle"�������������������AIDD_FOPT���g�������K�v�����B
1774     Opt = Yopt1K;
1775 maya 3227 FileVar->OpId = OpYSend;
1776     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1777     {
1778     if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_Y,&Opt) ||
1779     (FileVar->NumFname==0))
1780     {
1781     ProtoEnd();
1782     return;
1783     }
1784 yutakapon 3819 //ts.XmodemBin = Opt;
1785 maya 3227 }
1786     else
1787     (*SetFileVar)(FileVar);
1788     }
1789 doda 6363 else {
1790 maya 3227 FileVar->OpId = OpYRcv;
1791 yutakapon 3820 // �t�@�C���]�������I�v�V������"Yopt1K"�����������B
1792     Opt = Yopt1K;
1793 yutakapon 3821 (*SetFileVar)(FileVar);
1794 yutakapon 3820 }
1795 maya 3227
1796     TalkStatus = IdTalkQuiet;
1797    
1798     /* disable transmit delay (serial port) */
1799     cv.DelayFlag = FALSE;
1800    
1801     if (! OpenProtoDlg(FileVar,PROTO_YM,mode,Opt,0))
1802     ProtoEnd();
1803     }
1804     }
1805    
1806     extern "C" {
1807     void ZMODEMStart(int mode)
1808     {
1809     WORD Opt;
1810    
1811     if (! ProtoStart())
1812     return;
1813    
1814 doda 6361 if (mode == IdZSend || mode == IdZAutoS)
1815 maya 3227 {
1816     Opt = ts.XmodemBin;
1817     FileVar->OpId = OpZSend;
1818     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1819     {
1820     if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_Z,&Opt) ||
1821     (FileVar->NumFname==0))
1822     {
1823 doda 6364 if (mode == IdZAutoS) {
1824     CommRawOut(&cv, "\030\030\030\030\030\030\030\030\b\b\b\b\b\b\b\b\b\b", 18);
1825     }
1826 maya 3227 ProtoEnd();
1827     return;
1828     }
1829     ts.XmodemBin = Opt;
1830     }
1831     else
1832     (*SetFileVar)(FileVar);
1833     }
1834 doda 6361 else /* IdZReceive or IdZAutoR */
1835 maya 3227 FileVar->OpId = OpZRcv;
1836    
1837     TalkStatus = IdTalkQuiet;
1838    
1839     /* disable transmit delay (serial port) */
1840     cv.DelayFlag = FALSE;
1841    
1842     if (! OpenProtoDlg(FileVar,PROTO_ZM,mode,Opt,0))
1843     ProtoEnd();
1844     }
1845     }
1846    
1847     extern "C" {
1848     void BPStart(int mode)
1849     {
1850     LONG Option;
1851    
1852     if (! ProtoStart())
1853     return;
1854     if (mode==IdBPSend)
1855     {
1856     FileVar->OpId = OpBPSend;
1857     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1858     {
1859     FileVar->FullName[0] = 0;
1860     if (! (*GetTransFname)(FileVar, ts.FileDir, GTF_BP, &Option))
1861     {
1862     ProtoEnd();
1863     return;
1864     }
1865     }
1866     else
1867     (*SetFileVar)(FileVar);
1868     }
1869     else /* IdBPReceive or IdBPAuto */
1870     FileVar->OpId = OpBPRcv;
1871    
1872     TalkStatus = IdTalkQuiet;
1873    
1874     /* disable transmit delay (serial port) */
1875     cv.DelayFlag = FALSE;
1876    
1877     if (! OpenProtoDlg(FileVar,PROTO_BP,mode,0,0))
1878     ProtoEnd();
1879     }
1880     }
1881    
1882     extern "C" {
1883     void QVStart(int mode)
1884     {
1885     WORD W;
1886    
1887     if (! ProtoStart())
1888     return;
1889    
1890     if (mode==IdQVSend)
1891     {
1892     FileVar->OpId = OpQVSend;
1893     if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1894     {
1895     if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_QV, &W) ||
1896     (FileVar->NumFname==0))
1897     {
1898     ProtoEnd();
1899     return;
1900     }
1901     }
1902     else
1903     (*SetFileVar)(FileVar);
1904     }
1905     else
1906     FileVar->OpId = OpQVRcv;
1907    
1908     TalkStatus = IdTalkQuiet;
1909    
1910     /* disable transmit delay (serial port) */
1911     cv.DelayFlag = FALSE;
1912    
1913     if (! OpenProtoDlg(FileVar,PROTO_QV,mode,0,0))
1914     ProtoEnd();
1915     }
1916     }

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