Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/filesys_log.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6947 - (show annotations) (download) (as text)
Tue Oct 17 09:38:24 2017 UTC (6 years, 5 months ago) by doda
Original Path: trunk/teraterm/teraterm/filesys.cpp
File MIME type: text/x-c++src
File size: 46502 byte(s)
ログのタイムスタンプの種別として Elapsed を追加 #37528

要望のあったログ開始からの Elapsed Time の他に、接続開始からの Elapsed
Time も追加した。ログ取得を一旦終了した後に再度追記でログ取得を開始した
時に基準時間が同じになるので便利かなと。

LogTimestampUTC も時刻形式の一種と考えて、設定を共通化した。
LotTimestampType が設定済みの場合は LogTimestampUTC の設定は無視される。

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

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