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 8822 - (show annotations) (download) (as text)
Thu Jul 2 15:41:37 2020 UTC (3 years, 9 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/filesys.cpp
File MIME type: text/x-c++src
File size: 45118 byte(s)
ログが取れなくなっていたので修正

- 文字コードは UTF-8 固定
- 改行コードは CR+LF 固定
1 /*
2 * Copyright (C) 1994-1998 T. Teranishi
3 * (C) 2005-2020 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 <stdio.h>
32 #include <io.h>
33 #include <process.h>
34
35 #include "teraterm.h"
36 #include "tttypes.h"
37 #include "ttftypes.h"
38 #include "tt_res.h"
39 #include "ftdlg.h"
40 #include "protodlg.h"
41 #include "ttwinman.h"
42 #include "commlib.h"
43 #include "ttcommon.h"
44 #include "ttdde.h"
45 #include "ttlib.h"
46 #include "dlglib.h"
47 #include "vtterm.h"
48 #include "win16api.h"
49
50 #include "filesys.h"
51 #include "ftlib.h"
52
53 #include "buffer.h"
54
55 #include <io.h>
56 #include <process.h>
57
58 #define FS_BRACKET_NONE 0
59 #define FS_BRACKET_START 1
60 #define FS_BRACKET_END 2
61
62 PFileVar LogVar = NULL;
63 PFileVar SendVar = NULL;
64 PFileVar FileVar = NULL;
65 static PCHAR ProtoVar = NULL;
66 static int ProtoId;
67
68 BOOL FileLog = FALSE;
69 BOOL BinLog = FALSE;
70 BOOL DDELog = FALSE;
71 static BOOL FileRetrySend, FileRetryEcho, FileCRSend, FileReadEOF, BinaryMode;
72 static BYTE FileByte;
73
74 #define FILE_SEND_BUF_SIZE 8192
75 struct FileSendHandler {
76 CHAR buf[FILE_SEND_BUF_SIZE];
77 int pos;
78 int end;
79 };
80 static struct FileSendHandler FileSendHandler;
81 static int FileDlgRefresh;
82
83 static int FileBracketMode = FS_BRACKET_NONE;
84 static int FileBracketPtr = 0;
85 static char BracketStartStr[] = "\033[200~";
86 static char BracketEndStr[] = "\033[201~";
87
88 static BOOL FSend = FALSE;
89
90 HWND HWndLog = NULL; //steven add
91
92 static HMODULE HTTFILE = NULL;
93 static int TTFILECount = 0;
94
95 PGetSetupFname GetSetupFname;
96 PGetTransFname GetTransFname;
97 PGetMultiFname GetMultiFname;
98 PGetGetFname GetGetFname;
99 PSetFileVar SetFileVar;
100 PGetXFname GetXFname;
101 PProtoInit ProtoInit;
102 PProtoParse ProtoParse;
103 PProtoTimeOutProc ProtoTimeOutProc;
104 PProtoCancel ProtoCancel;
105 PTTFILESetUILanguageFile TTFILESetUILanguageFile;
106 PTTFILESetFileSendFilter TTFILESetFileSendFilter;
107
108 #define IdGetSetupFname 1
109 #define IdGetTransFname 2
110 #define IdGetMultiFname 3
111 #define IdGetGetFname 4
112 #define IdSetFileVar 5
113 #define IdGetXFname 6
114
115 #define IdProtoInit 7
116 #define IdProtoParse 8
117 #define IdProtoTimeOutProc 9
118 #define IdProtoCancel 10
119
120 #define IdTTFILESetUILanguageFile 11
121 #define IdTTFILESetFileSendFilter 12
122
123 /*
124 Line Head flag for timestamping
125 2007.05.24 Gentaro
126 */
127 enum enumLineEnd {
128 Line_Other = 0,
129 Line_LineHead = 1,
130 Line_FileHead = 2,
131 };
132
133 enum enumLineEnd eLineEnd = Line_LineHead;
134
135
136 // �x�����������p�X���b�h�����b�Z�[�W
137 #define WM_DPC_LOGTHREAD_SEND (WM_APP + 1)
138
139 static void CloseFileSync(PFileVar ptr);
140
141
142 BOOL LoadTTFILE()
143 {
144 BOOL Err;
145
146 if (HTTFILE != NULL)
147 {
148 TTFILECount++;
149 return TRUE;
150 }
151 else
152 TTFILECount = 0;
153
154 HTTFILE = LoadHomeDLL("TTPFILE.DLL");
155 if (HTTFILE == NULL)
156 return FALSE;
157
158 Err = FALSE;
159
160 GetSetupFname = (PGetSetupFname)GetProcAddress(HTTFILE,
161 MAKEINTRESOURCE(IdGetSetupFname));
162 if (GetSetupFname==NULL)
163 Err = TRUE;
164
165 GetTransFname = (PGetTransFname)GetProcAddress(HTTFILE,
166 MAKEINTRESOURCE(IdGetTransFname));
167 if (GetTransFname==NULL)
168 Err = TRUE;
169
170 GetMultiFname = (PGetMultiFname)GetProcAddress(HTTFILE,
171 MAKEINTRESOURCE(IdGetMultiFname));
172 if (GetMultiFname==NULL)
173 Err = TRUE;
174
175 GetGetFname = (PGetGetFname)GetProcAddress(HTTFILE,
176 MAKEINTRESOURCE(IdGetGetFname));
177 if (GetGetFname==NULL)
178 Err = TRUE;
179
180 SetFileVar = (PSetFileVar)GetProcAddress(HTTFILE,
181 MAKEINTRESOURCE(IdSetFileVar));
182 if (SetFileVar==NULL)
183 Err = TRUE;
184
185 GetXFname = (PGetXFname)GetProcAddress(HTTFILE,
186 MAKEINTRESOURCE(IdGetXFname));
187 if (GetXFname==NULL)
188 Err = TRUE;
189
190 ProtoInit = (PProtoInit)GetProcAddress(HTTFILE,
191 MAKEINTRESOURCE(IdProtoInit));
192 if (ProtoInit==NULL)
193 Err = TRUE;
194
195 ProtoParse = (PProtoParse)GetProcAddress(HTTFILE,
196 MAKEINTRESOURCE(IdProtoParse));
197 if (ProtoParse==NULL)
198 Err = TRUE;
199
200 ProtoTimeOutProc = (PProtoTimeOutProc)GetProcAddress(HTTFILE,
201 MAKEINTRESOURCE(IdProtoTimeOutProc));
202 if (ProtoTimeOutProc==NULL)
203 Err = TRUE;
204
205 ProtoCancel = (PProtoCancel)GetProcAddress(HTTFILE,
206 MAKEINTRESOURCE(IdProtoCancel));
207 if (ProtoCancel==NULL)
208 Err = TRUE;
209
210 TTFILESetUILanguageFile = (PTTFILESetUILanguageFile)GetProcAddress(HTTFILE,
211 MAKEINTRESOURCE(IdTTFILESetUILanguageFile));
212 if (TTFILESetUILanguageFile==NULL) {
213 Err = TRUE;
214 }
215 else {
216 TTFILESetUILanguageFile(ts.UILanguageFile);
217 }
218
219 TTFILESetFileSendFilter = (PTTFILESetFileSendFilter)GetProcAddress(HTTFILE,
220 MAKEINTRESOURCE(IdTTFILESetFileSendFilter));
221 if (TTFILESetFileSendFilter==NULL) {
222 Err = TRUE;
223 }
224 else {
225 TTFILESetFileSendFilter(ts.FileSendFilter);
226 }
227
228 if (Err)
229 {
230 FreeLibrary(HTTFILE);
231 HTTFILE = NULL;
232 return FALSE;
233 }
234 else {
235 TTFILECount = 1;
236 return TRUE;
237 }
238 }
239
240 BOOL FreeTTFILE()
241 {
242 if (TTFILECount==0)
243 return FALSE;
244 TTFILECount--;
245 if (TTFILECount>0)
246 return TRUE;
247 if (HTTFILE!=NULL)
248 {
249 FreeLibrary(HTTFILE);
250 HTTFILE = NULL;
251 }
252 return TRUE;
253 }
254
255 static PFileTransDlg FLogDlg = NULL;
256 static PFileTransDlg SendDlg = NULL;
257 static PProtoDlg PtDlg = NULL;
258
259 static BOOL OpenFTDlg(PFileVar fv)
260 {
261 PFileTransDlg FTDlg;
262
263 FTDlg = new CFileTransDlg();
264
265 fv->StartTime = 0;
266 fv->ProgStat = 0;
267
268 if (fv->OpId != OpLog) {
269 fv->HideDialog = ts.FTHideDialog;
270 }
271
272 if (FTDlg!=NULL)
273 {
274 FTDlg->Create(hInst, HVTWin, fv, &cv, &ts);
275 FTDlg->RefreshNum();
276 if (fv->OpId == OpLog) {
277 HWndLog = FTDlg->m_hWnd; // steven add
278 }
279 }
280
281 if (fv->OpId==OpLog)
282 FLogDlg = FTDlg; /* Log */
283 else
284 SendDlg = FTDlg; /* File send */
285
286 fv->StartTime = GetTickCount();
287 if (fv->OpId == OpSendFile) {
288 HWND HFTDlg = FTDlg->GetSafeHwnd();
289 InitDlgProgress(HFTDlg, IDC_TRANSPROGRESS, &fv->ProgStat);
290 ShowWindow(GetDlgItem(HFTDlg, IDC_TRANS_ELAPSED), SW_SHOW);
291 }
292
293 return (FTDlg!=NULL);
294 }
295
296 void ShowFTDlg(WORD OpId)
297 {
298 if (OpId == OpLog) {
299 if (FLogDlg != NULL) {
300 FLogDlg->ShowWindow(SW_SHOWNORMAL);
301 SetForegroundWindow(FLogDlg->GetSafeHwnd());
302 }
303 }
304 else {
305 if (SendDlg != NULL) {
306 SendDlg->ShowWindow(SW_SHOWNORMAL);
307 SetForegroundWindow(SendDlg->GetSafeHwnd());
308 }
309 }
310 }
311
312 BOOL NewFileVar(PFileVar *fv)
313 {
314 if ((*fv)==NULL)
315 {
316 *fv = (PFileVar)malloc(sizeof(TFileVar));
317 if ((*fv)!=NULL)
318 {
319 char FileDirExpanded[MAX_PATH];
320 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
321 memset(*fv, 0, sizeof(TFileVar));
322 strncpy_s((*fv)->FullName, sizeof((*fv)->FullName), FileDirExpanded, _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 != INVALID_HANDLE_VALUE) {
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 = INVALID_HANDLE_VALUE;
443 }
444 CloseHandle(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(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 BOOL LogStart()
485 {
486 LONG Option;
487 char *logdir;
488 unsigned tid;
489 DWORD ofs, size, written_size;
490 char buf[512];
491 const char *crlf = "\r\n";
492 DWORD crlf_len = 2;
493 char FileDirExpanded[MAX_PATH];
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 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
510 logdir = FileDirExpanded;
511 }
512 else {
513 logdir = ts.HomeDir;
514 }
515
516 if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0) {
517 Option = 0;
518 if (ts.LogBinary) {
519 Option |= LOGDLG_BINARY;
520 }
521 if (ts.Append) {
522 Option |= LOGDLG_APPEND;
523 }
524 if (ts.LogTypePlainText) {
525 Option |= LOGDLG_PLAINTEXT;
526 }
527 if (ts.LogTimestamp) {
528 Option |= LOGDLG_TIMESTAMP;
529 }
530 if (ts.LogHideDialog) {
531 Option |= LOGDLG_HIDEDIALOG;
532 }
533 if (ts.LogAllBuffIncludedInFirst) {
534 Option |= LOGDLG_INCSCRBUFF;
535 }
536
537 switch (ts.LogTimestampType) {
538 case TIMESTAMP_LOCAL:
539 // nothing to do
540 break;
541 case TIMESTAMP_UTC:
542 Option |= LOGDLG_UTC;
543 break;
544 case TIMESTAMP_ELAPSED_LOGSTART:
545 Option |= LOGDLG_ELAPSED;
546 break;
547 case TIMESTAMP_ELAPSED_CONNECTED:
548 Option |= LOGDLG_ELAPSED | LOGDLG_ELAPSEDCON;
549 break;
550 default:
551 // not reached
552 break;
553 }
554
555 // ���O���f�t�H���g�t�@�C���������� (2006.8.28 maya)
556 strncat_s(LogVar->FullName, sizeof(LogVar->FullName), ts.LogDefaultName, _TRUNCATE);
557 ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
558 ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
559
560 strncpy_s(LogVar->LogDefaultPath, sizeof(LogVar->LogDefaultPath), ts.LogDefaultPath, _TRUNCATE);
561 if (! (*GetTransFname)(LogVar, logdir, GTF_LOG, &Option)) {
562 FreeFileVar(&LogVar);
563 FreeTTFILE();
564 return FALSE;
565 }
566
567 ts.LogBinary = CheckFlag(Option, LOGDLG_BINARY);
568 CheckFlag(Option, LOGDLG_BINARY);
569 ts.Append =
570 CheckFlag(Option, LOGDLG_APPEND);
571 ts.LogTypePlainText =
572 CheckFlag(Option, LOGDLG_PLAINTEXT);
573 ts.LogTimestamp =
574 CheckFlag(Option, LOGDLG_TIMESTAMP);
575 ts.LogHideDialog =
576 CheckFlag(Option, LOGDLG_HIDEDIALOG);
577 ts.LogAllBuffIncludedInFirst =
578 CheckFlag(Option, LOGDLG_INCSCRBUFF);
579
580 if (Option & LOGDLG_ELAPSED) {
581 // �o������
582 if (Option & LOGDLG_ELAPSEDCON) {
583 ts.LogTimestampType = TIMESTAMP_ELAPSED_CONNECTED;
584 }
585 else {
586 ts.LogTimestampType = TIMESTAMP_ELAPSED_LOGSTART;
587 }
588 }
589 else {
590 // �����`��
591 if (Option & LOGDLG_UTC) {
592 ts.LogTimestampType = TIMESTAMP_UTC;
593 }
594 else {
595 ts.LogTimestampType = TIMESTAMP_LOCAL;
596 }
597 }
598 }
599 else {
600 // LogVar->DirLen = 0 ��������������
601 // �t���p�X�E�����p�X������ LogVar->FullName �������������K�v������
602 char FileName[MAX_PATH];
603
604 // �t���p�X��
605 strncpy_s(FileName, sizeof(FileName), LogVar->FullName, _TRUNCATE);
606 ConvFName(logdir, FileName, sizeof(FileName), "", LogVar->FullName, sizeof(LogVar->FullName));
607
608 ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
609 ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
610
611 (*SetFileVar)(LogVar);
612
613 FixLogOption();
614 }
615
616 if (ts.LogBinary > 0)
617 {
618 BinLog = TRUE;
619 FileLog = FALSE;
620 if (! CreateBinBuf())
621 {
622 FileTransEnd(OpLog);
623 return FALSE;
624 }
625 }
626 else {
627 BinLog = FALSE;
628 FileLog = TRUE;
629 if (! CreateLogBuf())
630 {
631 FileTransEnd(OpLog);
632 return FALSE;
633 }
634 }
635 cv.LStart = cv.LogPtr;
636 cv.LCount = 0;
637 if (ts.LogHideDialog)
638 LogVar->HideDialog = 1;
639
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 = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
650 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
651 if (LogVar->FileHandle != INVALID_HANDLE_VALUE){
652 SetFilePointer(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 = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
666 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
667 }
668 LogVar->FileOpen = (LogVar->FileHandle != INVALID_HANDLE_VALUE);
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(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(LogVar->FileHandle, buf, size, &written_size, NULL);
741 WriteFile(LogVar->FileHandle, crlf, crlf_len, &written_size, NULL);
742 #if 0
743 }
744 #endif
745 }
746 }
747
748 return TRUE;
749 }
750
751 void LogPut1(BYTE b)
752 {
753 cv.LogBuf[cv.LogPtr] = b;
754 cv.LogPtr++;
755 if (cv.LogPtr>=InBuffSize)
756 cv.LogPtr = cv.LogPtr-InBuffSize;
757
758 if (FileLog)
759 {
760 if (cv.LCount>=InBuffSize)
761 {
762 cv.LCount = InBuffSize;
763 cv.LStart = cv.LogPtr;
764 }
765 else
766 cv.LCount++;
767 }
768 else
769 cv.LCount = 0;
770
771 if (DDELog)
772 {
773 if (cv.DCount>=InBuffSize)
774 {
775 cv.DCount = InBuffSize;
776 cv.DStart = cv.LogPtr;
777 }
778 else
779 cv.DCount++;
780 }
781 else {
782 cv.DCount = 0;
783 // ���O���������}�N�����X�g�[���������������C���B
784 // ���O�����������x�}�N�����~�������A�o�b�t�@���C���f�b�N�X�������������������A
785 // ���x�}�N�������������������f�[�^�������������������B
786 // �}�N�������~���������������C���f�b�N�X�����������������������B
787 // (2006.12.26 yutaka)
788 cv.DStart = cv.LogPtr;
789 }
790 }
791
792 static BOOL Get1(PCHAR Buf, int *Start, int *Count, PBYTE b)
793 {
794 if (*Count<=0) return FALSE;
795 *b = Buf[*Start];
796 (*Start)++;
797 if (*Start>=InBuffSize)
798 *Start = *Start-InBuffSize;
799 (*Count)--;
800 return TRUE;
801 }
802
803
804
805 static CRITICAL_SECTION g_filelog_lock; /* ���b�N�p���� */
806
807 void logfile_lock_initialize(void)
808 {
809 InitializeCriticalSection(&g_filelog_lock);
810 }
811
812 static inline void logfile_lock(void)
813 {
814 EnterCriticalSection(&g_filelog_lock);
815 }
816
817 static inline void logfile_unlock(void)
818 {
819 LeaveCriticalSection(&g_filelog_lock);
820 }
821
822 // �R�����g�����O����������
823 void CommentLogToFile(char *buf, int size)
824 {
825 DWORD wrote;
826
827 if (LogVar == NULL || !LogVar->FileOpen) {
828 char uimsg[MAX_UIMSG];
829 get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
830 get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
831 "It is not opened by the log file yet.", ts.UILanguageFile);
832 ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
833 return;
834 }
835
836 logfile_lock();
837 WriteFile(LogVar->FileHandle, buf, size, &wrote, NULL);
838 WriteFile(LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
839 /* Set Line End Flag
840 2007.05.24 Gentaro
841 */
842 eLineEnd = Line_LineHead;
843 logfile_unlock();
844 }
845
846 // ���O�����[�e�[�g�����B
847 // (2013.3.21 yutaka)
848 static void LogRotate(void)
849 {
850 int loopmax = 10000; // XXX
851 char filename[1024];
852 char newfile[1024], oldfile[1024];
853 int i, k;
854 int dwShareMode = FILE_SHARE_READ;
855 unsigned tid;
856
857 if (! LogVar->FileOpen) return;
858
859 if (LogVar->RotateMode == ROTATE_NONE)
860 return;
861
862 if (LogVar->RotateMode == ROTATE_SIZE) {
863 if (LogVar->ByteCount <= LogVar->RotateSize)
864 return;
865 //OutputDebugPrintf("%s: mode %d size %ld\n", __FUNCTION__, LogVar->RotateMode, LogVar->ByteCount);
866 } else {
867 return;
868 }
869
870 logfile_lock();
871 // ���O�T�C�Y���������������B
872 LogVar->ByteCount = 0;
873
874 // �������������t�@�C�����N���[�Y�����A�������t�@�C�����I�[�v�������B
875 CloseFileSync(LogVar);
876 //_lclose(LogVar->FileHandle);
877
878 // �������[�e�[�V�������X�e�b�v�����w����������
879 if (LogVar->RotateStep > 0)
880 loopmax = LogVar->RotateStep;
881
882 for (i = 1 ; i <= loopmax ; i++) {
883 _snprintf_s(filename, sizeof(filename), _TRUNCATE, "%s.%d", LogVar->FullName, i);
884 if (_access_s(filename, 0) != 0)
885 break;
886 }
887 if (i > loopmax) {
888 // �������������������������A�������t�@�C�������p�������B
889 i = loopmax;
890 }
891
892 // ���t�@�C�������l�[���B
893 for (k = i-1 ; k >= 0 ; k--) {
894 if (k == 0)
895 strncpy_s(oldfile, sizeof(oldfile), LogVar->FullName, _TRUNCATE);
896 else
897 _snprintf_s(oldfile, sizeof(oldfile), _TRUNCATE, "%s.%d", LogVar->FullName, k);
898 _snprintf_s(newfile, sizeof(newfile), _TRUNCATE, "%s.%d", LogVar->FullName, k+1);
899 remove(newfile);
900 if (rename(oldfile, newfile) != 0) {
901 OutputDebugPrintf("%s: rename %d\n", __FUNCTION__, errno);
902 }
903 }
904
905 // ���I�[�v��
906 if (!ts.LogLockExclusive) {
907 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
908 }
909 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
910 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
911
912 // �x�����������p�X���b�h���N�����B
913 // (2013.4.19 yutaka)
914 // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
915 // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
916 // �����������������C�������B
917 // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
918 // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
919 // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
920 // (2016.9.26 yutaka)
921 LogVar->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
922 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
923 LogVar->LogThreadId = tid;
924 if (LogVar->LogThreadEvent != NULL) {
925 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
926 CloseHandle(LogVar->LogThreadEvent);
927 }
928
929 logfile_unlock();
930
931 }
932
933 void LogToFile()
934 {
935 PCHAR Buf;
936 int Start, Count;
937 BYTE b;
938 PCHAR WriteBuf;
939 DWORD WriteBufMax, WriteBufLen;
940 CHAR tmp[128];
941 DWORD wrote;
942
943 if (! LogVar->FileOpen) return;
944 if (FileLog)
945 {
946 Buf = cv.LogBuf;
947 Start = cv.LStart;
948 Count = cv.LCount;
949 }
950 else if (BinLog)
951 {
952 Buf = cv.BinBuf;
953 Start = cv.BStart;
954 Count = cv.BCount;
955 }
956 else
957 return;
958
959 if (Buf==NULL) return;
960 if (Count==0) return;
961
962 // ���b�N������(2004.8.6 yutaka)
963 logfile_lock();
964
965 if (ts.DeferredLogWriteMode) {
966 WriteBufMax = 8192;
967 WriteBufLen = 0;
968 WriteBuf = (PCHAR)malloc(WriteBufMax);
969 while (Get1(Buf,&Start,&Count,&b)) {
970 if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
971 {
972 tmp[0] = 0;
973 if ( ts.LogTimestamp && eLineEnd ) {
974 char *strtime = NULL;
975
976 switch (ts.LogTimestampType) {
977 case TIMESTAMP_LOCAL:
978 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
979 break;
980 case TIMESTAMP_UTC:
981 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
982 break;
983 case TIMESTAMP_ELAPSED_LOGSTART:
984 strtime = strelapsed(LogVar->StartTime);
985 break;
986 case TIMESTAMP_ELAPSED_CONNECTED:
987 strtime = strelapsed(cv.ConnectedTime);
988 break;
989 }
990
991 /* 2007.05.24 Gentaro */
992 if( eLineEnd == Line_FileHead ){
993 strncat_s(tmp, sizeof(tmp), "\r\n", _TRUNCATE);
994 }
995 strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE);
996 strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE);
997 strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE);
998 }
999
1000 /* 2007.05.24 Gentaro */
1001 if( b == 0x0a ){
1002 eLineEnd = Line_LineHead; /* set endmark*/
1003 }
1004 else {
1005 eLineEnd = Line_Other; /* clear endmark*/
1006 }
1007
1008 if (WriteBufLen >= (WriteBufMax*4/5)) {
1009 WriteBufMax *= 2;
1010 WriteBuf = (PCHAR)realloc(WriteBuf, WriteBufMax);
1011 }
1012 memcpy(&WriteBuf[WriteBufLen], tmp, strlen(tmp));
1013 WriteBufLen += strlen(tmp);
1014 WriteBuf[WriteBufLen++] = b;
1015
1016 (LogVar->ByteCount)++;
1017 }
1018 }
1019
1020 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)WriteBuf, WriteBufLen);
1021
1022 } else {
1023
1024 while (Get1(Buf,&Start,&Count,&b))
1025 {
1026 if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
1027 {
1028 if ( ts.LogTimestamp && eLineEnd ) {
1029 char *strtime = NULL;
1030
1031 switch (ts.LogTimestampType) {
1032 case TIMESTAMP_LOCAL:
1033 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1034 break;
1035 case TIMESTAMP_UTC:
1036 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1037 break;
1038 case TIMESTAMP_ELAPSED_LOGSTART:
1039 strtime = strelapsed(LogVar->StartTime);
1040 break;
1041 case TIMESTAMP_ELAPSED_CONNECTED:
1042 strtime = strelapsed(cv.ConnectedTime);
1043 break;
1044 }
1045 WriteFile(LogVar->FileHandle, "[", 1, &wrote, NULL);
1046 WriteFile(LogVar->FileHandle, strtime, strlen(strtime), &wrote, NULL);
1047 WriteFile(LogVar->FileHandle, "] ", 2, &wrote, NULL);
1048 }
1049
1050 /* 2007.05.24 Gentaro */
1051 if( b == 0x0a ){
1052 eLineEnd = Line_LineHead; /* set endmark*/
1053 }
1054 else {
1055 eLineEnd = Line_Other; /* clear endmark*/
1056 }
1057
1058 WriteFile(LogVar->FileHandle, (PCHAR)&b, 1, &wrote, NULL);
1059 (LogVar->ByteCount)++;
1060 }
1061 }
1062
1063 }
1064
1065 logfile_unlock();
1066
1067 if (FileLog)
1068 {
1069 cv.LStart = Start;
1070 cv.LCount = Count;
1071 }
1072 else {
1073 cv.BStart = Start;
1074 cv.BCount = Count;
1075 }
1076 if (((cv.FilePause & OpLog) !=0) || cv.ProtoFlag) return;
1077 if (FLogDlg!=NULL)
1078 FLogDlg->RefreshNum();
1079
1080 // ���O�E���[�e�[�g
1081 LogRotate();
1082
1083 }
1084
1085 BOOL CreateLogBuf()
1086 {
1087 if (cv.HLogBuf==NULL)
1088 {
1089 cv.HLogBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1090 cv.LogBuf = NULL;
1091 cv.LogPtr = 0;
1092 cv.LStart = 0;
1093 cv.LCount = 0;
1094 cv.DStart = 0;
1095 cv.DCount = 0;
1096 }
1097 return (cv.HLogBuf!=NULL);
1098 }
1099
1100 void FreeLogBuf()
1101 {
1102 if ((cv.HLogBuf==NULL) || FileLog || DDELog)
1103 return;
1104 if (cv.LogBuf!=NULL)
1105 GlobalUnlock(cv.HLogBuf);
1106 GlobalFree(cv.HLogBuf);
1107 cv.HLogBuf = NULL;
1108 cv.LogBuf = NULL;
1109 cv.LogPtr = 0;
1110 cv.LStart = 0;
1111 cv.LCount = 0;
1112 cv.DStart = 0;
1113 cv.DCount = 0;
1114 }
1115
1116 BOOL CreateBinBuf()
1117 {
1118 if (cv.HBinBuf==NULL)
1119 {
1120 cv.HBinBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1121 cv.BinBuf = NULL;
1122 cv.BinPtr = 0;
1123 cv.BStart = 0;
1124 cv.BCount = 0;
1125 }
1126 return (cv.HBinBuf!=NULL);
1127 }
1128
1129 void FreeBinBuf()
1130 {
1131 if ((cv.HBinBuf==NULL) || BinLog)
1132 return;
1133 if (cv.BinBuf!=NULL)
1134 GlobalUnlock(cv.HBinBuf);
1135 GlobalFree(cv.HBinBuf);
1136 cv.HBinBuf = NULL;
1137 cv.BinBuf = NULL;
1138 cv.BinPtr = 0;
1139 cv.BStart = 0;
1140 cv.BCount = 0;
1141 }
1142
1143 void FileSendStart()
1144 {
1145 LONG Option = 0;
1146
1147 if (! cv.Ready || FSend) return;
1148 if (cv.ProtoFlag)
1149 {
1150 FreeFileVar(&SendVar);
1151 return;
1152 }
1153
1154 if (! LoadTTFILE())
1155 return;
1156 if (! NewFileVar(&SendVar))
1157 {
1158 FreeTTFILE();
1159 return;
1160 }
1161 SendVar->OpId = OpSendFile;
1162
1163 FSend = TRUE;
1164
1165 if (strlen(&(SendVar->FullName[SendVar->DirLen])) == 0) {
1166 char FileDirExpanded[MAX_PATH];
1167 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1168 if (ts.TransBin)
1169 Option |= LOGDLG_BINARY;
1170 SendVar->FullName[0] = 0;
1171 if (! (*GetTransFname)(SendVar, FileDirExpanded, GTF_SEND, &Option)) {
1172 FileTransEnd(OpSendFile);
1173 return;
1174 }
1175 ts.TransBin = CheckFlag(Option, LOGDLG_BINARY);
1176 }
1177 else
1178 (*SetFileVar)(SendVar);
1179
1180 SendVar->FileHandle = CreateFile(SendVar->FullName, GENERIC_READ, FILE_SHARE_READ, NULL,
1181 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1182 SendVar->FileOpen = (SendVar->FileHandle != INVALID_HANDLE_VALUE);
1183 if (! SendVar->FileOpen)
1184 {
1185 FileTransEnd(OpSendFile);
1186 return;
1187 }
1188 SendVar->ByteCount = 0;
1189 SendVar->FileSize = GetFSize(SendVar->FullName);
1190
1191 TalkStatus = IdTalkFile;
1192 FileRetrySend = FALSE;
1193 FileRetryEcho = FALSE;
1194 FileCRSend = FALSE;
1195 FileReadEOF = FALSE;
1196 FileSendHandler.pos = 0;
1197 FileSendHandler.end = 0;
1198 FileDlgRefresh = 0;
1199
1200 if (BracketedPasteMode()) {
1201 FileBracketMode = FS_BRACKET_START;
1202 FileBracketPtr = 0;
1203 BinaryMode = TRUE;
1204 }
1205 else {
1206 FileBracketMode = FS_BRACKET_NONE;
1207 BinaryMode = ts.TransBin;
1208 }
1209
1210 if (! OpenFTDlg(SendVar))
1211 FileTransEnd(OpSendFile);
1212 }
1213
1214 void FileTransEnd(WORD OpId)
1215 /* OpId = 0: close Log and FileSend
1216 OpLog: close Log
1217 OpSendFile: close FileSend */
1218 {
1219 if (((OpId==0) || (OpId==OpLog)) && (FileLog || BinLog))
1220 {
1221 FileLog = FALSE;
1222 BinLog = FALSE;
1223 if (FLogDlg!=NULL)
1224 {
1225 FLogDlg->DestroyWindow();
1226 FLogDlg = NULL;
1227 HWndLog = NULL; // steven add
1228 }
1229 FreeFileVar(&LogVar);
1230 FreeLogBuf();
1231 FreeBinBuf();
1232 FreeTTFILE();
1233 }
1234
1235 if (((OpId==0) || (OpId==OpSendFile)) && FSend)
1236 {
1237 FSend = FALSE;
1238 TalkStatus = IdTalkKeyb;
1239 if (SendDlg!=NULL)
1240 {
1241 SendDlg->DestroyWindow();
1242 SendDlg = NULL;
1243 }
1244 FreeFileVar(&SendVar);
1245 FreeTTFILE();
1246 }
1247
1248 EndDdeCmnd(0);
1249 }
1250
1251 int FSOut1(BYTE b)
1252 {
1253 if (BinaryMode)
1254 return CommBinaryOut(&cv,(PCHAR)&b,1);
1255 else if ((b>=0x20) || (b==0x09) || (b==0x0A) || (b==0x0D))
1256 return CommTextOut(&cv,(PCHAR)&b,1);
1257 else
1258 return 1;
1259 }
1260
1261 int FSEcho1(BYTE b)
1262 {
1263 if (BinaryMode)
1264 return CommBinaryEcho(&cv,(PCHAR)&b,1);
1265 else
1266 return CommTextEcho(&cv,(PCHAR)&b,1);
1267 }
1268
1269 // �������������������������g��
1270 // - BinaryMode == true
1271 // - FileBracketMode == false
1272 // - cv.TelFlag == false
1273 // - ts.LocalEcho == 0
1274 void FileSendBinayBoost()
1275 {
1276 WORD c, fc;
1277 LONG BCOld;
1278 DWORD read_bytes;
1279
1280 if ((SendDlg == NULL) ||
1281 ((cv.FilePause & OpSendFile) != 0))
1282 return;
1283
1284 BCOld = SendVar->ByteCount;
1285
1286 if (FileRetrySend)
1287 {
1288 c = CommRawOut(&cv, &(FileSendHandler.buf[FileSendHandler.pos]),
1289 FileSendHandler.end - FileSendHandler.pos);
1290 FileSendHandler.pos += c;
1291 FileRetrySend = (FileSendHandler.end != FileSendHandler.pos);
1292 if (FileRetrySend)
1293 return;
1294 }
1295
1296 do {
1297 if (FileSendHandler.pos == FileSendHandler.end) {
1298 ReadFile(SendVar->FileHandle, &(FileSendHandler.buf[0]), sizeof(FileSendHandler.buf), &read_bytes, NULL);
1299 fc = LOWORD(read_bytes);
1300 FileSendHandler.pos = 0;
1301 FileSendHandler.end = fc;
1302 } else {
1303 fc = FileSendHandler.end - FileSendHandler.end;
1304 }
1305
1306 if (fc != 0)
1307 {
1308 c = CommRawOut(&cv, &(FileSendHandler.buf[FileSendHandler.pos]),
1309 FileSendHandler.end - FileSendHandler.pos);
1310 FileSendHandler.pos += c;
1311 FileRetrySend = (FileSendHandler.end != FileSendHandler.pos);
1312 SendVar->ByteCount = SendVar->ByteCount + c;
1313 if (FileRetrySend)
1314 {
1315 if (SendVar->ByteCount != BCOld)
1316 SendDlg->RefreshNum();
1317 return;
1318 }
1319 }
1320 FileDlgRefresh = SendVar->ByteCount;
1321 SendDlg->RefreshNum();
1322 BCOld = SendVar->ByteCount;
1323 if (fc != 0)
1324 return;
1325 } while (fc != 0);
1326
1327 FileTransEnd(OpSendFile);
1328 }
1329
1330 void FileSend()
1331 {
1332 WORD c, fc;
1333 LONG BCOld;
1334 DWORD read_bytes;
1335
1336 if (cv.PortType == IdSerial && ts.FileSendHighSpeedMode &&
1337 BinaryMode && !FileBracketMode && !cv.TelFlag &&
1338 (ts.LocalEcho == 0) && (ts.Baud >= 115200)) {
1339 return FileSendBinayBoost();
1340 }
1341
1342 if ((SendDlg==NULL) ||
1343 ((cv.FilePause & OpSendFile) !=0))
1344 return;
1345
1346 BCOld = SendVar->ByteCount;
1347
1348 if (FileRetrySend)
1349 {
1350 FileRetryEcho = (ts.LocalEcho>0);
1351 c = FSOut1(FileByte);
1352 FileRetrySend = (c==0);
1353 if (FileRetrySend)
1354 return;
1355 }
1356
1357 if (FileRetryEcho)
1358 {
1359 c = FSEcho1(FileByte);
1360 FileRetryEcho = (c==0);
1361 if (FileRetryEcho)
1362 return;
1363 }
1364
1365 do {
1366 if (FileBracketMode == FS_BRACKET_START) {
1367 FileByte = BracketStartStr[FileBracketPtr++];
1368 fc = 1;
1369
1370 if (FileBracketPtr >= sizeof(BracketStartStr) - 1) {
1371 FileBracketMode = FS_BRACKET_END;
1372 FileBracketPtr = 0;
1373 BinaryMode = ts.TransBin;
1374 }
1375 }
1376 else if (! FileReadEOF) {
1377 ReadFile(SendVar->FileHandle, &FileByte, 1, &read_bytes, NULL);
1378 fc = LOWORD(read_bytes);
1379 SendVar->ByteCount = SendVar->ByteCount + fc;
1380
1381 if (FileCRSend && (fc==1) && (FileByte==0x0A)) {
1382 ReadFile(SendVar->FileHandle, &FileByte, 1, &read_bytes, NULL);
1383 fc = LOWORD(read_bytes);
1384 SendVar->ByteCount = SendVar->ByteCount + fc;
1385 }
1386 }
1387 else {
1388 fc = 0;
1389 }
1390
1391 if (fc == 0 && FileBracketMode == FS_BRACKET_END) {
1392 FileReadEOF = TRUE;
1393 FileByte = BracketEndStr[FileBracketPtr++];
1394 fc = 1;
1395 BinaryMode = TRUE;
1396
1397 if (FileBracketPtr >= sizeof(BracketEndStr) - 1) {
1398 FileBracketMode = FS_BRACKET_NONE;
1399 FileBracketPtr = 0;
1400 }
1401 }
1402
1403
1404 if (fc!=0)
1405 {
1406 c = FSOut1(FileByte);
1407 FileCRSend = (ts.TransBin==0) && (FileByte==0x0D);
1408 FileRetrySend = (c==0);
1409 if (FileRetrySend)
1410 {
1411 if (SendVar->ByteCount != BCOld)
1412 SendDlg->RefreshNum();
1413 return;
1414 }
1415 if (ts.LocalEcho>0)
1416 {
1417 c = FSEcho1(FileByte);
1418 FileRetryEcho = (c==0);
1419 if (FileRetryEcho)
1420 return;
1421 }
1422 }
1423 if ((fc==0) || ((SendVar->ByteCount % 100 == 0) && (FileBracketPtr == 0))) {
1424 SendDlg->RefreshNum();
1425 BCOld = SendVar->ByteCount;
1426 if (fc!=0)
1427 return;
1428 }
1429 } while (fc!=0);
1430
1431 FileTransEnd(OpSendFile);
1432 }
1433
1434 void FLogChangeButton(BOOL Pause)
1435 {
1436 if (FLogDlg!=NULL)
1437 FLogDlg->ChangeButton(Pause);
1438 }
1439
1440 void FLogRefreshNum()
1441 {
1442 if (FLogDlg!=NULL)
1443 FLogDlg->RefreshNum();
1444 }
1445
1446 BOOL OpenProtoDlg(PFileVar fv, int IdProto, int Mode, WORD Opt1, WORD Opt2)
1447 {
1448 int vsize;
1449 PProtoDlg pd;
1450
1451 ProtoId = IdProto;
1452
1453 switch (ProtoId) {
1454 case PROTO_KMT:
1455 vsize = sizeof(TKmtVar);
1456 break;
1457 case PROTO_XM:
1458 vsize = sizeof(TXVar);
1459 break;
1460 case PROTO_YM:
1461 vsize = sizeof(TYVar);
1462 break;
1463 case PROTO_ZM:
1464 vsize = sizeof(TZVar);
1465 break;
1466 case PROTO_BP:
1467 vsize = sizeof(TBPVar);
1468 break;
1469 case PROTO_QV:
1470 vsize = sizeof(TQVVar);
1471 break;
1472 }
1473 ProtoVar = (PCHAR)malloc(vsize);
1474 if (ProtoVar==NULL)
1475 return FALSE;
1476
1477 switch (ProtoId) {
1478 case PROTO_KMT:
1479 ((PKmtVar)ProtoVar)->KmtMode = Mode;
1480 break;
1481 case PROTO_XM:
1482 ((PXVar)ProtoVar)->XMode = Mode;
1483 ((PXVar)ProtoVar)->XOpt = Opt1;
1484 ((PXVar)ProtoVar)->TextFlag = 1 - (Opt2 & 1);
1485 break;
1486 case PROTO_YM:
1487 ((PYVar)ProtoVar)->YMode = Mode;
1488 ((PYVar)ProtoVar)->YOpt = Opt1;
1489 break;
1490 case PROTO_ZM:
1491 ((PZVar)ProtoVar)->BinFlag = (Opt1 & 1) != 0;
1492 ((PZVar)ProtoVar)->ZMode = Mode;
1493 break;
1494 case PROTO_BP:
1495 ((PBPVar)ProtoVar)->BPMode = Mode;
1496 break;
1497 case PROTO_QV:
1498 ((PQVVar)ProtoVar)->QVMode = Mode;
1499 break;
1500 }
1501
1502 pd = new CProtoDlg();
1503 if (pd==NULL)
1504 {
1505 free(ProtoVar);
1506 ProtoVar = NULL;
1507 return FALSE;
1508 }
1509 pd->Create(hInst, HVTWin, fv, &ts);
1510
1511 (*ProtoInit)(ProtoId,FileVar,ProtoVar,&cv,&ts);
1512
1513 PtDlg = pd;
1514 return TRUE;
1515 }
1516
1517 void CloseProtoDlg()
1518 {
1519 if (PtDlg!=NULL)
1520 {
1521 PtDlg->DestroyWindow();
1522 PtDlg = NULL;
1523
1524 ::KillTimer(FileVar->HMainWin,IdProtoTimer);
1525 if ((ProtoId==PROTO_QV) &&
1526 (((PQVVar)ProtoVar)->QVMode==IdQVSend))
1527 CommTextOut(&cv,"\015",1);
1528 if (FileVar->LogFlag)
1529 CloseHandle(FileVar->LogFile);
1530 FileVar->LogFile = 0;
1531 if (ProtoVar!=NULL)
1532 {
1533 free(ProtoVar);
1534 ProtoVar = NULL;
1535 }
1536 }
1537 }
1538
1539 BOOL ProtoStart()
1540 {
1541 if (cv.ProtoFlag)
1542 return FALSE;
1543 if (FSend)
1544 {
1545 FreeFileVar(&FileVar);
1546 return FALSE;
1547 }
1548
1549 if (! LoadTTFILE())
1550 return FALSE;
1551 NewFileVar(&FileVar);
1552
1553 if (FileVar==NULL)
1554 {
1555 FreeTTFILE();
1556 return FALSE;
1557 }
1558 cv.ProtoFlag = TRUE;
1559 return TRUE;
1560 }
1561
1562 void ProtoEnd()
1563 {
1564 if (! cv.ProtoFlag)
1565 return;
1566 cv.ProtoFlag = FALSE;
1567
1568 /* Enable transmit delay (serial port) */
1569 cv.DelayFlag = TRUE;
1570 TalkStatus = IdTalkKeyb;
1571
1572 CloseProtoDlg();
1573
1574 if ((FileVar!=NULL) && FileVar->Success)
1575 EndDdeCmnd(1);
1576 else
1577 EndDdeCmnd(0);
1578
1579 FreeTTFILE();
1580 FreeFileVar(&FileVar);
1581 }
1582
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 void ProtoDlgTimeOut()
1601 {
1602 if (PtDlg!=NULL)
1603 (*ProtoTimeOutProc)(ProtoId,FileVar,ProtoVar,&cv);
1604 }
1605
1606 void ProtoDlgCancel()
1607 {
1608 if ((PtDlg!=NULL) &&
1609 (*ProtoCancel)(ProtoId,FileVar,ProtoVar,&cv))
1610 ProtoEnd();
1611 }
1612
1613 void KermitStart(int mode)
1614 {
1615 WORD w;
1616
1617 if (! ProtoStart())
1618 return;
1619
1620 switch (mode) {
1621 case IdKmtSend:
1622 FileVar->OpId = OpKmtSend;
1623 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1624 {
1625 char FileDirExpanded[MAX_PATH];
1626 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1627 if (!(*GetMultiFname)(FileVar, FileDirExpanded, GMF_KERMIT, &w) ||
1628 (FileVar->NumFname==0))
1629 {
1630 ProtoEnd();
1631 return;
1632 }
1633 }
1634 else
1635 (*SetFileVar)(FileVar);
1636 break;
1637 case IdKmtReceive:
1638 FileVar->OpId = OpKmtRcv;
1639 break;
1640 case IdKmtGet:
1641 FileVar->OpId = OpKmtSend;
1642 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1643 {
1644 if (! (*GetGetFname)(FileVar->HMainWin,FileVar) ||
1645 (strlen(FileVar->FullName)==0))
1646 {
1647 ProtoEnd();
1648 return;
1649 }
1650 }
1651 else
1652 (*SetFileVar)(FileVar);
1653 break;
1654 case IdKmtFinish:
1655 FileVar->OpId = OpKmtFin;
1656 break;
1657 default:
1658 ProtoEnd();
1659 return;
1660 }
1661 TalkStatus = IdTalkQuiet;
1662
1663 /* disable transmit delay (serial port) */
1664 cv.DelayFlag = FALSE;
1665
1666 if (! OpenProtoDlg(FileVar,PROTO_KMT,mode,0,0))
1667 ProtoEnd();
1668 }
1669
1670 void XMODEMStart(int mode)
1671 {
1672 LONG Option;
1673 int tmp;
1674
1675 if (! ProtoStart())
1676 return;
1677
1678 if (mode==IdXReceive)
1679 FileVar->OpId = OpXRcv;
1680 else
1681 FileVar->OpId = OpXSend;
1682
1683 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1684 {
1685 char FileDirExpanded[MAX_PATH];
1686 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1687 Option = MAKELONG(ts.XmodemBin,ts.XmodemOpt);
1688 if (! (*GetXFname)(FileVar->HMainWin,
1689 mode==IdXReceive,&Option,FileVar,FileDirExpanded))
1690 {
1691 ProtoEnd();
1692 return;
1693 }
1694 tmp = HIWORD(Option);
1695 if (mode == IdXReceive) {
1696 if (IsXoptCRC(tmp)) {
1697 if (IsXopt1k(ts.XmodemOpt)) {
1698 ts.XmodemOpt = Xopt1kCRC;
1699 }
1700 else {
1701 ts.XmodemOpt = XoptCRC;
1702 }
1703 }
1704 else {
1705 if (IsXopt1k(ts.XmodemOpt)) {
1706 ts.XmodemOpt = Xopt1kCksum;
1707 }
1708 else {
1709 ts.XmodemOpt = XoptCheck;
1710 }
1711 }
1712 ts.XmodemBin = LOWORD(Option);
1713 }
1714 else {
1715 if (IsXopt1k(tmp)) {
1716 if (IsXoptCRC(ts.XmodemOpt)) {
1717 ts.XmodemOpt = Xopt1kCRC;
1718 }
1719 else {
1720 ts.XmodemOpt = Xopt1kCksum;
1721 }
1722 }
1723 else {
1724 if (IsXoptCRC(ts.XmodemOpt)) {
1725 ts.XmodemOpt = XoptCRC;
1726 }
1727 else {
1728 ts.XmodemOpt = XoptCheck;
1729 }
1730 }
1731 }
1732 }
1733 else
1734 (*SetFileVar)(FileVar);
1735
1736 if (mode==IdXReceive)
1737 FileVar->FileHandle = _lcreat(FileVar->FullName,0);
1738 else
1739 FileVar->FileHandle = _lopen(FileVar->FullName,OF_READ);
1740
1741 FileVar->FileOpen = FileVar->FileHandle != INVALID_HANDLE_VALUE;
1742 if (! FileVar->FileOpen)
1743 {
1744 ProtoEnd();
1745 return;
1746 }
1747 TalkStatus = IdTalkQuiet;
1748
1749 /* disable transmit delay (serial port) */
1750 cv.DelayFlag = FALSE;
1751
1752 if (! OpenProtoDlg(FileVar,PROTO_XM,mode,
1753 ts.XmodemOpt,ts.XmodemBin))
1754 ProtoEnd();
1755 }
1756
1757 void YMODEMStart(int mode)
1758 {
1759 WORD Opt;
1760
1761 if (! ProtoStart())
1762 return;
1763
1764 if (mode==IdYSend)
1765 {
1766 char FileDirExpanded[MAX_PATH];
1767 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1768
1769 // �t�@�C���]�������I�v�V������"Yopt1K"�����������B
1770 // TODO: "Yopt1K", "YoptG", "YoptSingle"�������������������AIDD_FOPT���g�������K�v�����B
1771 Opt = Yopt1K;
1772 FileVar->OpId = OpYSend;
1773 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1774 {
1775 if (! (*GetMultiFname)(FileVar,FileDirExpanded,GMF_Y,&Opt) ||
1776 (FileVar->NumFname==0))
1777 {
1778 ProtoEnd();
1779 return;
1780 }
1781 //ts.XmodemBin = Opt;
1782 }
1783 else
1784 (*SetFileVar)(FileVar);
1785 }
1786 else {
1787 FileVar->OpId = OpYRcv;
1788 // �t�@�C���]�������I�v�V������"Yopt1K"�����������B
1789 Opt = Yopt1K;
1790 (*SetFileVar)(FileVar);
1791 }
1792
1793 TalkStatus = IdTalkQuiet;
1794
1795 /* disable transmit delay (serial port) */
1796 cv.DelayFlag = FALSE;
1797
1798 if (! OpenProtoDlg(FileVar,PROTO_YM,mode,Opt,0))
1799 ProtoEnd();
1800 }
1801
1802 void ZMODEMStart(int mode)
1803 {
1804 WORD Opt;
1805
1806 if (! ProtoStart())
1807 return;
1808
1809 if (mode == IdZSend || mode == IdZAutoS)
1810 {
1811 Opt = ts.XmodemBin;
1812 FileVar->OpId = OpZSend;
1813 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1814 {
1815 char FileDirExpanded[MAX_PATH];
1816 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1817 if (! (*GetMultiFname)(FileVar,FileDirExpanded,GMF_Z,&Opt) ||
1818 (FileVar->NumFname==0))
1819 {
1820 if (mode == IdZAutoS) {
1821 CommRawOut(&cv, "\030\030\030\030\030\030\030\030\b\b\b\b\b\b\b\b\b\b", 18);
1822 }
1823 ProtoEnd();
1824 return;
1825 }
1826 ts.XmodemBin = Opt;
1827 }
1828 else
1829 (*SetFileVar)(FileVar);
1830 }
1831 else /* IdZReceive or IdZAutoR */
1832 FileVar->OpId = OpZRcv;
1833
1834 TalkStatus = IdTalkQuiet;
1835
1836 /* disable transmit delay (serial port) */
1837 cv.DelayFlag = FALSE;
1838
1839 if (! OpenProtoDlg(FileVar,PROTO_ZM,mode,Opt,0))
1840 ProtoEnd();
1841 }
1842
1843 void BPStart(int mode)
1844 {
1845 LONG Option = 0;
1846
1847 if (! ProtoStart())
1848 return;
1849 if (mode==IdBPSend)
1850 {
1851 FileVar->OpId = OpBPSend;
1852 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1853 {
1854 char FileDirExpanded[MAX_PATH];
1855 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1856 FileVar->FullName[0] = 0;
1857 if (! (*GetTransFname)(FileVar, FileDirExpanded, GTF_BP, &Option))
1858 {
1859 ProtoEnd();
1860 return;
1861 }
1862 }
1863 else
1864 (*SetFileVar)(FileVar);
1865 }
1866 else /* IdBPReceive or IdBPAuto */
1867 FileVar->OpId = OpBPRcv;
1868
1869 TalkStatus = IdTalkQuiet;
1870
1871 /* disable transmit delay (serial port) */
1872 cv.DelayFlag = FALSE;
1873
1874 if (! OpenProtoDlg(FileVar,PROTO_BP,mode,0,0))
1875 ProtoEnd();
1876 }
1877
1878 void QVStart(int mode)
1879 {
1880 WORD W;
1881
1882 if (! ProtoStart())
1883 return;
1884
1885 if (mode==IdQVSend)
1886 {
1887 FileVar->OpId = OpQVSend;
1888 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1889 {
1890 char FileDirExpanded[MAX_PATH];
1891 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1892 if (! (*GetMultiFname)(FileVar,FileDirExpanded,GMF_QV, &W) ||
1893 (FileVar->NumFname==0))
1894 {
1895 ProtoEnd();
1896 return;
1897 }
1898 }
1899 else
1900 (*SetFileVar)(FileVar);
1901 }
1902 else
1903 FileVar->OpId = OpQVRcv;
1904
1905 TalkStatus = IdTalkQuiet;
1906
1907 /* disable transmit delay (serial port) */
1908 cv.DelayFlag = FALSE;
1909
1910 if (! OpenProtoDlg(FileVar,PROTO_QV,mode,0,0))
1911 ProtoEnd();
1912 }

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