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

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