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 7930 - (show annotations) (download) (as text)
Fri Aug 9 13:36:46 2019 UTC (4 years, 8 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/filesys.cpp
File MIME type: text/x-c++src
File size: 44227 byte(s)
不要なHANDLEキャストを削除

- コンパイラの型チェックを積極的に利用するのが目的
- 出力されるコードは特に変化ない
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 memset(*fv, 0, sizeof(TFileVar));
322 strncpy_s((*fv)->FullName, sizeof((*fv)->FullName),ts.FileDir, _TRUNCATE);
323 AppendSlash((*fv)->FullName,sizeof((*fv)->FullName));
324 (*fv)->DirLen = strlen((*fv)->FullName);
325 (*fv)->FileOpen = FALSE;
326 (*fv)->OverWrite = ((ts.FTFlag & FT_RENAME) == 0);
327 (*fv)->HMainWin = HVTWin;
328 (*fv)->Success = FALSE;
329 (*fv)->NoMsg = FALSE;
330 (*fv)->HideDialog = FALSE;
331 }
332 }
333
334 return ((*fv)!=NULL);
335 }
336
337 void FreeFileVar(PFileVar *fv)
338 {
339 if ((*fv)!=NULL)
340 {
341 CloseFileSync(*fv);
342 //if ((*fv)->FileOpen) _lclose((*fv)->FileHandle);
343 if ((*fv)->FnStrMemHandle != 0)
344 {
345 GlobalUnlock((*fv)->FnStrMemHandle);
346 GlobalFree((*fv)->FnStrMemHandle);
347 }
348 free(*fv);
349 *fv = NULL;
350 }
351 }
352
353 // &h ���z�X�g�����u�� (2007.5.14)
354 // &p ��TCP�|�[�g�������u�� (2009.6.12)
355 void ConvertLogname(char *c, int destlen)
356 {
357 char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
358 char tmphost[1024];
359 char tmpuser[256+1];
360 DWORD len_user = sizeof(tmpuser);
361
362 memset(buf, 0, sizeof(buf));
363
364 while(*p != '\0') {
365 if (*p == '&' && *(p+1) != '\0') {
366 switch (*(p+1)) {
367 case 'h':
368 if (cv.Open) {
369 if (cv.PortType == IdTCPIP) {
370 // �z�X�g����IPv6�A�h���X�����A�t�@�C�������g�p�����������������������A
371 // �]�v�����������������B
372 // (2013.3.9 yutaka)
373 strncpy_s(tmphost, sizeof(tmphost), ts.HostName, _TRUNCATE);
374 //strncpy_s(tmphost, sizeof(tmphost), "2001:0db8:bd05:01d2:288a:1fc0:0001:10ee", _TRUNCATE);
375 replaceInvalidFileNameChar(tmphost, '_');
376 strncat_s(buf,sizeof(buf), tmphost, _TRUNCATE);
377 }
378 else if (cv.PortType == IdSerial) {
379 strncpy_s(buf2,sizeof(buf2),buf,_TRUNCATE);
380 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%sCOM%d", buf2, ts.ComPort);
381 }
382 }
383 break;
384 case 'p':
385 if (cv.Open) {
386 if (cv.PortType == IdTCPIP) {
387 char port[6];
388 _snprintf_s(port, sizeof(port), _TRUNCATE, "%d", ts.TCPPort);
389 strncat_s(buf,sizeof(buf),port,_TRUNCATE);
390 }
391 }
392 break;
393 case 'u':
394 if (GetUserName(tmpuser, &len_user) != 0) {
395 strncat_s(buf,sizeof(buf),tmpuser,_TRUNCATE);
396 }
397 break;
398 default:
399 strncpy_s(buf2,sizeof(buf2),p,2);
400 strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
401 }
402 p++;
403 }
404 else {
405 strncpy_s(buf2,sizeof(buf2),p,1);
406 strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
407 }
408 p++;
409 }
410 strncpy_s(c, destlen, buf, _TRUNCATE);
411 }
412
413 void FixLogOption()
414 {
415 if (ts.LogBinary) {
416 ts.LogTypePlainText = false;
417 ts.LogTimestamp = false;
418 }
419 }
420
421
422 // �X���b�h���I�����t�@�C�����N���[�Y
423 static void CloseFileSync(PFileVar ptr)
424 {
425 BOOL ret;
426 DWORD code;
427
428 if (!ptr->FileOpen)
429 return;
430
431 if (ptr->LogThread != 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
494 if ((FileLog) || (BinLog)) return FALSE;
495
496 if (! LoadTTFILE()) return FALSE;
497 if (! NewFileVar(&LogVar))
498 {
499 FreeTTFILE();
500 return FALSE;
501 }
502 LogVar->OpId = OpLog;
503
504 if (strlen(ts.LogDefaultPath) > 0) {
505 logdir = ts.LogDefaultPath;
506 }
507 else if (strlen(ts.FileDir) > 0) {
508 logdir = ts.FileDir;
509 }
510 else {
511 logdir = ts.HomeDir;
512 }
513
514 if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0) {
515 Option = 0;
516 if (ts.LogBinary) {
517 Option |= LOGDLG_BINARY;
518 }
519 if (ts.Append) {
520 Option |= LOGDLG_APPEND;
521 }
522 if (ts.LogTypePlainText) {
523 Option |= LOGDLG_PLAINTEXT;
524 }
525 if (ts.LogTimestamp) {
526 Option |= LOGDLG_TIMESTAMP;
527 }
528 if (ts.LogHideDialog) {
529 Option |= LOGDLG_HIDEDIALOG;
530 }
531 if (ts.LogAllBuffIncludedInFirst) {
532 Option |= LOGDLG_INCSCRBUFF;
533 }
534
535 switch (ts.LogTimestampType) {
536 case TIMESTAMP_LOCAL:
537 // nothing to do
538 break;
539 case TIMESTAMP_UTC:
540 Option |= LOGDLG_UTC;
541 break;
542 case TIMESTAMP_ELAPSED_LOGSTART:
543 Option |= LOGDLG_ELAPSED;
544 break;
545 case TIMESTAMP_ELAPSED_CONNECTED:
546 Option |= LOGDLG_ELAPSED | LOGDLG_ELAPSEDCON;
547 break;
548 default:
549 // not reached
550 break;
551 }
552
553 // ���O���f�t�H���g�t�@�C���������� (2006.8.28 maya)
554 strncat_s(LogVar->FullName, sizeof(LogVar->FullName), ts.LogDefaultName, _TRUNCATE);
555 ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
556 ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
557
558 strncpy_s(LogVar->LogDefaultPath, sizeof(LogVar->LogDefaultPath), ts.LogDefaultPath, _TRUNCATE);
559 if (! (*GetTransFname)(LogVar, logdir, GTF_LOG, &Option)) {
560 FreeFileVar(&LogVar);
561 FreeTTFILE();
562 return FALSE;
563 }
564
565 ts.LogBinary = CheckFlag(Option, LOGDLG_BINARY);
566 CheckFlag(Option, LOGDLG_BINARY);
567 ts.Append =
568 CheckFlag(Option, LOGDLG_APPEND);
569 ts.LogTypePlainText =
570 CheckFlag(Option, LOGDLG_PLAINTEXT);
571 ts.LogTimestamp =
572 CheckFlag(Option, LOGDLG_TIMESTAMP);
573 ts.LogHideDialog =
574 CheckFlag(Option, LOGDLG_HIDEDIALOG);
575 ts.LogAllBuffIncludedInFirst =
576 CheckFlag(Option, LOGDLG_INCSCRBUFF);
577
578 if (Option & LOGDLG_ELAPSED) {
579 // �o������
580 if (Option & LOGDLG_ELAPSEDCON) {
581 ts.LogTimestampType = TIMESTAMP_ELAPSED_CONNECTED;
582 }
583 else {
584 ts.LogTimestampType = TIMESTAMP_ELAPSED_LOGSTART;
585 }
586 }
587 else {
588 // �����`��
589 if (Option & LOGDLG_UTC) {
590 ts.LogTimestampType = TIMESTAMP_UTC;
591 }
592 else {
593 ts.LogTimestampType = TIMESTAMP_LOCAL;
594 }
595 }
596 }
597 else {
598 // LogVar->DirLen = 0 ��������������
599 // �t���p�X�E�����p�X������ LogVar->FullName �������������K�v������
600 char FileName[MAX_PATH];
601
602 // �t���p�X��
603 strncpy_s(FileName, sizeof(FileName), LogVar->FullName, _TRUNCATE);
604 ConvFName(logdir, FileName, sizeof(FileName), "", LogVar->FullName, sizeof(LogVar->FullName));
605
606 ParseStrftimeFileName(LogVar->FullName, sizeof(LogVar->FullName));
607 ConvertLogname(LogVar->FullName, sizeof(LogVar->FullName));
608
609 (*SetFileVar)(LogVar);
610
611 FixLogOption();
612 }
613
614 if (ts.LogBinary > 0)
615 {
616 BinLog = TRUE;
617 FileLog = FALSE;
618 if (! CreateBinBuf())
619 {
620 FileTransEnd(OpLog);
621 return FALSE;
622 }
623 }
624 else {
625 BinLog = FALSE;
626 FileLog = TRUE;
627 if (! CreateLogBuf())
628 {
629 FileTransEnd(OpLog);
630 return FALSE;
631 }
632 }
633 cv.LStart = cv.LogPtr;
634 cv.LCount = 0;
635 if (ts.LogHideDialog)
636 LogVar->HideDialog = 1;
637
638 HelpId = HlpFileLog;
639 /* 2007.05.24 Gentaro */
640 eLineEnd = Line_LineHead;
641
642 if (ts.Append > 0)
643 {
644 int dwShareMode = FILE_SHARE_READ;
645 if (!ts.LogLockExclusive) {
646 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
647 }
648 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
649 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
650 if (LogVar->FileHandle != INVALID_HANDLE_VALUE){
651 SetFilePointer(LogVar->FileHandle, 0, NULL, FILE_END);
652 /* 2007.05.24 Gentaro
653 If log file already exists,
654 a newline is inserted before the first timestamp.
655 */
656 eLineEnd = Line_FileHead;
657 }
658 }
659 else {
660 int dwShareMode = FILE_SHARE_READ;
661 if (!ts.LogLockExclusive) {
662 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
663 }
664 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
665 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
666 }
667 LogVar->FileOpen = (LogVar->FileHandle != INVALID_HANDLE_VALUE);
668 if (! LogVar->FileOpen)
669 {
670 char msg[128];
671
672 // �t�@�C���I�[�v���G���[�������b�Z�[�W�\�������������B(2008.7.9 yutaka)
673 if (LogVar->NoMsg == FALSE) {
674 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Can not create a `%s' file. (%d)", LogVar->FullName, GetLastError());
675 MessageBox(NULL, msg, "Tera Term: File open error", MB_OK | MB_ICONERROR);
676 }
677
678 FileTransEnd(OpLog);
679 return FALSE;
680 }
681 LogVar->ByteCount = 0;
682
683 // Log rotate configuration
684 LogVar->RotateMode = ts.LogRotate;
685 LogVar->RotateSize = ts.LogRotateSize;
686 LogVar->RotateStep = ts.LogRotateStep;
687
688 // Log rotate���L���������A�����t�@�C���T�C�Y�����������B
689 // �������t�@�C�������������T�C�Y�����[�e�[�g�������������C���B
690 // (2016.4.9 yutaka)
691 if (LogVar->RotateMode != ROTATE_NONE) {
692 size = GetFileSize(LogVar->FileHandle, NULL);
693 if (size != -1)
694 LogVar->ByteCount = size;
695 }
696
697 if (! OpenFTDlg(LogVar)) {
698 FileTransEnd(OpLog);
699 return FALSE;
700 }
701
702 // �x�����������p�X���b�h���N�����B
703 // (2013.4.19 yutaka)
704 // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
705 // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
706 // �����������������C�������B
707 // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
708 // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
709 // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
710 // (2016.9.23 yutaka)
711 LogVar->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
712 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
713 LogVar->LogThreadId = tid;
714 if (LogVar->LogThreadEvent != NULL) {
715 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
716 CloseHandle(LogVar->LogThreadEvent);
717 }
718
719 // �����o�b�t�@�������f�[�^�������������o���������A
720 // ���O�������J�n�����B
721 // (2013.9.29 yutaka)
722 if (ts.LogAllBuffIncludedInFirst) {
723 for (ofs = 0 ; ; ofs++ ) {
724 // 1�����s�����������B���������������A�G�X�P�[�v�V�[�P���X�������������B
725 size = BuffGetAnyLineData(ofs, buf, sizeof(buf));
726 if (size == -1)
727 break;
728
729 #if 0
730 if (ts.DeferredLogWriteMode) { // �x����������
731 char *pbuf = (char *)malloc(size + 2);
732 memcpy(pbuf, buf, size);
733 pbuf[size] = '\r';
734 pbuf[size+1] = '\n';
735 Sleep(1); // �X���b�h�L���[�����������������A�R���e�L�X�g�X�C�b�`�������B
736 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)pbuf, size + 2);
737 } else { // �������B�l�b�g���[�N�o�R�����x���B
738 #endif
739 WriteFile(LogVar->FileHandle, buf, size, &written_size, NULL);
740 WriteFile(LogVar->FileHandle, crlf, crlf_len, &written_size, NULL);
741 #if 0
742 }
743 #endif
744 }
745 }
746
747 return TRUE;
748 }
749
750 void LogPut1(BYTE b)
751 {
752 LogLast = b;
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 void Log1Byte(BYTE b)
793 {
794 if (b==0x0d)
795 {
796 LogLast = b;
797 return;
798 }
799 if ((b==0x0a) && (LogLast==0x0d))
800 LogPut1(0x0d);
801 LogPut1(b);
802 }
803
804 static BOOL Get1(PCHAR Buf, int *Start, int *Count, PBYTE b)
805 {
806 if (*Count<=0) return FALSE;
807 *b = Buf[*Start];
808 (*Start)++;
809 if (*Start>=InBuffSize)
810 *Start = *Start-InBuffSize;
811 (*Count)--;
812 return TRUE;
813 }
814
815
816
817 static CRITICAL_SECTION g_filelog_lock; /* ���b�N�p���� */
818
819 void logfile_lock_initialize(void)
820 {
821 InitializeCriticalSection(&g_filelog_lock);
822 }
823
824 static inline void logfile_lock(void)
825 {
826 EnterCriticalSection(&g_filelog_lock);
827 }
828
829 static inline void logfile_unlock(void)
830 {
831 LeaveCriticalSection(&g_filelog_lock);
832 }
833
834 // �R�����g�����O����������
835 void CommentLogToFile(char *buf, int size)
836 {
837 DWORD wrote;
838
839 if (LogVar == NULL || !LogVar->FileOpen) {
840 char uimsg[MAX_UIMSG];
841 get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
842 get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
843 "It is not opened by the log file yet.", ts.UILanguageFile);
844 ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
845 return;
846 }
847
848 logfile_lock();
849 WriteFile(LogVar->FileHandle, buf, size, &wrote, NULL);
850 WriteFile(LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
851 /* Set Line End Flag
852 2007.05.24 Gentaro
853 */
854 eLineEnd = Line_LineHead;
855 logfile_unlock();
856 }
857
858 // ���O�����[�e�[�g�����B
859 // (2013.3.21 yutaka)
860 static void LogRotate(void)
861 {
862 int loopmax = 10000; // XXX
863 char filename[1024];
864 char newfile[1024], oldfile[1024];
865 int i, k;
866 int dwShareMode = FILE_SHARE_READ;
867 unsigned tid;
868
869 if (! LogVar->FileOpen) return;
870
871 if (LogVar->RotateMode == ROTATE_NONE)
872 return;
873
874 if (LogVar->RotateMode == ROTATE_SIZE) {
875 if (LogVar->ByteCount <= LogVar->RotateSize)
876 return;
877 //OutputDebugPrintf("%s: mode %d size %ld\n", __FUNCTION__, LogVar->RotateMode, LogVar->ByteCount);
878 } else {
879 return;
880 }
881
882 logfile_lock();
883 // ���O�T�C�Y���������������B
884 LogVar->ByteCount = 0;
885
886 // �������������t�@�C�����N���[�Y�����A�������t�@�C�����I�[�v�������B
887 CloseFileSync(LogVar);
888 //_lclose(LogVar->FileHandle);
889
890 // �������[�e�[�V�������X�e�b�v�����w����������
891 if (LogVar->RotateStep > 0)
892 loopmax = LogVar->RotateStep;
893
894 for (i = 1 ; i <= loopmax ; i++) {
895 _snprintf_s(filename, sizeof(filename), _TRUNCATE, "%s.%d", LogVar->FullName, i);
896 if (_access_s(filename, 0) != 0)
897 break;
898 }
899 if (i > loopmax) {
900 // �������������������������A�������t�@�C�������p�������B
901 i = loopmax;
902 }
903
904 // ���t�@�C�������l�[���B
905 for (k = i-1 ; k >= 0 ; k--) {
906 if (k == 0)
907 strncpy_s(oldfile, sizeof(oldfile), LogVar->FullName, _TRUNCATE);
908 else
909 _snprintf_s(oldfile, sizeof(oldfile), _TRUNCATE, "%s.%d", LogVar->FullName, k);
910 _snprintf_s(newfile, sizeof(newfile), _TRUNCATE, "%s.%d", LogVar->FullName, k+1);
911 remove(newfile);
912 if (rename(oldfile, newfile) != 0) {
913 OutputDebugPrintf("%s: rename %d\n", __FUNCTION__, errno);
914 }
915 }
916
917 // ���I�[�v��
918 if (!ts.LogLockExclusive) {
919 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
920 }
921 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
922 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
923
924 // �x�����������p�X���b�h���N�����B
925 // (2013.4.19 yutaka)
926 // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
927 // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
928 // �����������������C�������B
929 // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
930 // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
931 // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
932 // (2016.9.26 yutaka)
933 LogVar->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
934 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
935 LogVar->LogThreadId = tid;
936 if (LogVar->LogThreadEvent != NULL) {
937 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
938 CloseHandle(LogVar->LogThreadEvent);
939 }
940
941 logfile_unlock();
942
943 }
944
945 void LogToFile()
946 {
947 PCHAR Buf;
948 int Start, Count;
949 BYTE b;
950 PCHAR WriteBuf;
951 DWORD WriteBufMax, WriteBufLen;
952 CHAR tmp[128];
953 DWORD wrote;
954
955 if (! LogVar->FileOpen) return;
956 if (FileLog)
957 {
958 Buf = cv.LogBuf;
959 Start = cv.LStart;
960 Count = cv.LCount;
961 }
962 else if (BinLog)
963 {
964 Buf = cv.BinBuf;
965 Start = cv.BStart;
966 Count = cv.BCount;
967 }
968 else
969 return;
970
971 if (Buf==NULL) return;
972 if (Count==0) return;
973
974 // ���b�N������(2004.8.6 yutaka)
975 logfile_lock();
976
977 if (ts.DeferredLogWriteMode) {
978 WriteBufMax = 8192;
979 WriteBufLen = 0;
980 WriteBuf = (PCHAR)malloc(WriteBufMax);
981 while (Get1(Buf,&Start,&Count,&b)) {
982 if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
983 {
984 tmp[0] = 0;
985 if ( ts.LogTimestamp && eLineEnd ) {
986 char *strtime = NULL;
987
988 switch (ts.LogTimestampType) {
989 case TIMESTAMP_LOCAL:
990 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
991 break;
992 case TIMESTAMP_UTC:
993 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
994 break;
995 case TIMESTAMP_ELAPSED_LOGSTART:
996 strtime = strelapsed(LogVar->StartTime);
997 break;
998 case TIMESTAMP_ELAPSED_CONNECTED:
999 strtime = strelapsed(cv.ConnectedTime);
1000 break;
1001 }
1002
1003 /* 2007.05.24 Gentaro */
1004 if( eLineEnd == Line_FileHead ){
1005 strncat_s(tmp, sizeof(tmp), "\r\n", _TRUNCATE);
1006 }
1007 strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE);
1008 strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE);
1009 strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE);
1010 }
1011
1012 /* 2007.05.24 Gentaro */
1013 if( b == 0x0a ){
1014 eLineEnd = Line_LineHead; /* set endmark*/
1015 }
1016 else {
1017 eLineEnd = Line_Other; /* clear endmark*/
1018 }
1019
1020 if (WriteBufLen >= (WriteBufMax*4/5)) {
1021 WriteBufMax *= 2;
1022 WriteBuf = (PCHAR)realloc(WriteBuf, WriteBufMax);
1023 }
1024 memcpy(&WriteBuf[WriteBufLen], tmp, strlen(tmp));
1025 WriteBufLen += strlen(tmp);
1026 WriteBuf[WriteBufLen++] = b;
1027
1028 (LogVar->ByteCount)++;
1029 }
1030 }
1031
1032 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)WriteBuf, WriteBufLen);
1033
1034 } else {
1035
1036 while (Get1(Buf,&Start,&Count,&b))
1037 {
1038 if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
1039 {
1040 if ( ts.LogTimestamp && eLineEnd ) {
1041 char *strtime = NULL;
1042
1043 switch (ts.LogTimestampType) {
1044 case TIMESTAMP_LOCAL:
1045 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1046 break;
1047 case TIMESTAMP_UTC:
1048 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1049 break;
1050 case TIMESTAMP_ELAPSED_LOGSTART:
1051 strtime = strelapsed(LogVar->StartTime);
1052 break;
1053 case TIMESTAMP_ELAPSED_CONNECTED:
1054 strtime = strelapsed(cv.ConnectedTime);
1055 break;
1056 }
1057 WriteFile(LogVar->FileHandle, "[", 1, &wrote, NULL);
1058 WriteFile(LogVar->FileHandle, strtime, strlen(strtime), &wrote, NULL);
1059 WriteFile(LogVar->FileHandle, "] ", 2, &wrote, NULL);
1060 }
1061
1062 /* 2007.05.24 Gentaro */
1063 if( b == 0x0a ){
1064 eLineEnd = Line_LineHead; /* set endmark*/
1065 }
1066 else {
1067 eLineEnd = Line_Other; /* clear endmark*/
1068 }
1069
1070 WriteFile(LogVar->FileHandle, (PCHAR)&b, 1, &wrote, NULL);
1071 (LogVar->ByteCount)++;
1072 }
1073 }
1074
1075 }
1076
1077 logfile_unlock();
1078
1079 if (FileLog)
1080 {
1081 cv.LStart = Start;
1082 cv.LCount = Count;
1083 }
1084 else {
1085 cv.BStart = Start;
1086 cv.BCount = Count;
1087 }
1088 if (((cv.FilePause & OpLog) !=0) || cv.ProtoFlag) return;
1089 if (FLogDlg!=NULL)
1090 FLogDlg->RefreshNum();
1091
1092 // ���O�E���[�e�[�g
1093 LogRotate();
1094
1095 }
1096
1097 BOOL CreateLogBuf()
1098 {
1099 if (cv.HLogBuf==NULL)
1100 {
1101 cv.HLogBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1102 cv.LogBuf = NULL;
1103 cv.LogPtr = 0;
1104 cv.LStart = 0;
1105 cv.LCount = 0;
1106 cv.DStart = 0;
1107 cv.DCount = 0;
1108 }
1109 return (cv.HLogBuf!=NULL);
1110 }
1111
1112 void FreeLogBuf()
1113 {
1114 if ((cv.HLogBuf==NULL) || FileLog || DDELog)
1115 return;
1116 if (cv.LogBuf!=NULL)
1117 GlobalUnlock(cv.HLogBuf);
1118 GlobalFree(cv.HLogBuf);
1119 cv.HLogBuf = NULL;
1120 cv.LogBuf = NULL;
1121 cv.LogPtr = 0;
1122 cv.LStart = 0;
1123 cv.LCount = 0;
1124 cv.DStart = 0;
1125 cv.DCount = 0;
1126 }
1127
1128 BOOL CreateBinBuf()
1129 {
1130 if (cv.HBinBuf==NULL)
1131 {
1132 cv.HBinBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1133 cv.BinBuf = NULL;
1134 cv.BinPtr = 0;
1135 cv.BStart = 0;
1136 cv.BCount = 0;
1137 }
1138 return (cv.HBinBuf!=NULL);
1139 }
1140
1141 void FreeBinBuf()
1142 {
1143 if ((cv.HBinBuf==NULL) || BinLog)
1144 return;
1145 if (cv.BinBuf!=NULL)
1146 GlobalUnlock(cv.HBinBuf);
1147 GlobalFree(cv.HBinBuf);
1148 cv.HBinBuf = NULL;
1149 cv.BinBuf = NULL;
1150 cv.BinPtr = 0;
1151 cv.BStart = 0;
1152 cv.BCount = 0;
1153 }
1154
1155 void FileSendStart()
1156 {
1157 LONG Option = 0;
1158
1159 if (! cv.Ready || FSend) return;
1160 if (cv.ProtoFlag)
1161 {
1162 FreeFileVar(&SendVar);
1163 return;
1164 }
1165
1166 if (! LoadTTFILE())
1167 return;
1168 if (! NewFileVar(&SendVar))
1169 {
1170 FreeTTFILE();
1171 return;
1172 }
1173 SendVar->OpId = OpSendFile;
1174
1175 FSend = TRUE;
1176
1177 if (strlen(&(SendVar->FullName[SendVar->DirLen]))==0) {
1178 if (ts.TransBin)
1179 Option |= LOGDLG_BINARY;
1180 SendVar->FullName[0] = 0;
1181 if (! (*GetTransFname)(SendVar, ts.FileDir, GTF_SEND, &Option)) {
1182 FileTransEnd(OpSendFile);
1183 return;
1184 }
1185 ts.TransBin = CheckFlag(Option, LOGDLG_BINARY);
1186 }
1187 else
1188 (*SetFileVar)(SendVar);
1189
1190 SendVar->FileHandle = CreateFile(SendVar->FullName, GENERIC_READ, FILE_SHARE_READ, NULL,
1191 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1192 SendVar->FileOpen = (SendVar->FileHandle != INVALID_HANDLE_VALUE);
1193 if (! SendVar->FileOpen)
1194 {
1195 FileTransEnd(OpSendFile);
1196 return;
1197 }
1198 SendVar->ByteCount = 0;
1199 SendVar->FileSize = GetFSize(SendVar->FullName);
1200
1201 TalkStatus = IdTalkFile;
1202 FileRetrySend = FALSE;
1203 FileRetryEcho = FALSE;
1204 FileCRSend = FALSE;
1205 FileReadEOF = FALSE;
1206 FileSendHandler.pos = 0;
1207 FileSendHandler.end = 0;
1208 FileDlgRefresh = 0;
1209
1210 if (BracketedPasteMode()) {
1211 FileBracketMode = FS_BRACKET_START;
1212 FileBracketPtr = 0;
1213 BinaryMode = TRUE;
1214 }
1215 else {
1216 FileBracketMode = FS_BRACKET_NONE;
1217 BinaryMode = ts.TransBin;
1218 }
1219
1220 if (! OpenFTDlg(SendVar))
1221 FileTransEnd(OpSendFile);
1222 }
1223
1224 void FileTransEnd(WORD OpId)
1225 /* OpId = 0: close Log and FileSend
1226 OpLog: close Log
1227 OpSendFile: close FileSend */
1228 {
1229 if (((OpId==0) || (OpId==OpLog)) && (FileLog || BinLog))
1230 {
1231 FileLog = FALSE;
1232 BinLog = FALSE;
1233 if (FLogDlg!=NULL)
1234 {
1235 FLogDlg->DestroyWindow();
1236 FLogDlg = NULL;
1237 HWndLog = NULL; // steven add
1238 }
1239 FreeFileVar(&LogVar);
1240 FreeLogBuf();
1241 FreeBinBuf();
1242 FreeTTFILE();
1243 }
1244
1245 if (((OpId==0) || (OpId==OpSendFile)) && FSend)
1246 {
1247 FSend = FALSE;
1248 TalkStatus = IdTalkKeyb;
1249 if (SendDlg!=NULL)
1250 {
1251 SendDlg->DestroyWindow();
1252 SendDlg = NULL;
1253 }
1254 FreeFileVar(&SendVar);
1255 FreeTTFILE();
1256 }
1257
1258 EndDdeCmnd(0);
1259 }
1260
1261 int FSOut1(BYTE b)
1262 {
1263 if (BinaryMode)
1264 return CommBinaryOut(&cv,(PCHAR)&b,1);
1265 else if ((b>=0x20) || (b==0x09) || (b==0x0A) || (b==0x0D))
1266 return CommTextOut(&cv,(PCHAR)&b,1);
1267 else
1268 return 1;
1269 }
1270
1271 int FSEcho1(BYTE b)
1272 {
1273 if (BinaryMode)
1274 return CommBinaryEcho(&cv,(PCHAR)&b,1);
1275 else
1276 return CommTextEcho(&cv,(PCHAR)&b,1);
1277 }
1278
1279 // �������������������������g��
1280 // - BinaryMode == true
1281 // - FileBracketMode == false
1282 // - cv.TelFlag == false
1283 // - ts.LocalEcho == 0
1284 void FileSendBinayBoost()
1285 {
1286 WORD c, fc;
1287 LONG BCOld;
1288 DWORD read_bytes;
1289
1290 if ((SendDlg == NULL) ||
1291 ((cv.FilePause & OpSendFile) != 0))
1292 return;
1293
1294 BCOld = SendVar->ByteCount;
1295
1296 if (FileRetrySend)
1297 {
1298 c = CommRawOut(&cv, &(FileSendHandler.buf[FileSendHandler.pos]),
1299 FileSendHandler.end - FileSendHandler.pos);
1300 FileSendHandler.pos += c;
1301 FileRetrySend = (FileSendHandler.end != FileSendHandler.pos);
1302 if (FileRetrySend)
1303 return;
1304 }
1305
1306 do {
1307 if (FileSendHandler.pos == FileSendHandler.end) {
1308 ReadFile(SendVar->FileHandle, &(FileSendHandler.buf[0]), sizeof(FileSendHandler.buf), &read_bytes, NULL);
1309 fc = LOWORD(read_bytes);
1310 FileSendHandler.pos = 0;
1311 FileSendHandler.end = fc;
1312 } else {
1313 fc = FileSendHandler.end - FileSendHandler.end;
1314 }
1315
1316 if (fc != 0)
1317 {
1318 c = CommRawOut(&cv, &(FileSendHandler.buf[FileSendHandler.pos]),
1319 FileSendHandler.end - FileSendHandler.pos);
1320 FileSendHandler.pos += c;
1321 FileRetrySend = (FileSendHandler.end != FileSendHandler.pos);
1322 SendVar->ByteCount = SendVar->ByteCount + c;
1323 if (FileRetrySend)
1324 {
1325 if (SendVar->ByteCount != BCOld)
1326 SendDlg->RefreshNum();
1327 return;
1328 }
1329 }
1330 FileDlgRefresh = SendVar->ByteCount;
1331 SendDlg->RefreshNum();
1332 BCOld = SendVar->ByteCount;
1333 if (fc != 0)
1334 return;
1335 } while (fc != 0);
1336
1337 FileTransEnd(OpSendFile);
1338 }
1339
1340 void FileSend()
1341 {
1342 WORD c, fc;
1343 LONG BCOld;
1344 DWORD read_bytes;
1345
1346 if (cv.PortType == IdSerial && ts.FileSendHighSpeedMode &&
1347 BinaryMode && !FileBracketMode && !cv.TelFlag &&
1348 (ts.LocalEcho == 0) && (ts.Baud >= 115200)) {
1349 return FileSendBinayBoost();
1350 }
1351
1352 if ((SendDlg==NULL) ||
1353 ((cv.FilePause & OpSendFile) !=0))
1354 return;
1355
1356 BCOld = SendVar->ByteCount;
1357
1358 if (FileRetrySend)
1359 {
1360 FileRetryEcho = (ts.LocalEcho>0);
1361 c = FSOut1(FileByte);
1362 FileRetrySend = (c==0);
1363 if (FileRetrySend)
1364 return;
1365 }
1366
1367 if (FileRetryEcho)
1368 {
1369 c = FSEcho1(FileByte);
1370 FileRetryEcho = (c==0);
1371 if (FileRetryEcho)
1372 return;
1373 }
1374
1375 do {
1376 if (FileBracketMode == FS_BRACKET_START) {
1377 FileByte = BracketStartStr[FileBracketPtr++];
1378 fc = 1;
1379
1380 if (FileBracketPtr >= sizeof(BracketStartStr) - 1) {
1381 FileBracketMode = FS_BRACKET_END;
1382 FileBracketPtr = 0;
1383 BinaryMode = ts.TransBin;
1384 }
1385 }
1386 else if (! FileReadEOF) {
1387 ReadFile(SendVar->FileHandle, &FileByte, 1, &read_bytes, NULL);
1388 fc = LOWORD(read_bytes);
1389 SendVar->ByteCount = SendVar->ByteCount + fc;
1390
1391 if (FileCRSend && (fc==1) && (FileByte==0x0A)) {
1392 ReadFile(SendVar->FileHandle, &FileByte, 1, &read_bytes, NULL);
1393 fc = LOWORD(read_bytes);
1394 SendVar->ByteCount = SendVar->ByteCount + fc;
1395 }
1396 }
1397 else {
1398 fc = 0;
1399 }
1400
1401 if (fc == 0 && FileBracketMode == FS_BRACKET_END) {
1402 FileReadEOF = TRUE;
1403 FileByte = BracketEndStr[FileBracketPtr++];
1404 fc = 1;
1405 BinaryMode = TRUE;
1406
1407 if (FileBracketPtr >= sizeof(BracketEndStr) - 1) {
1408 FileBracketMode = FS_BRACKET_NONE;
1409 FileBracketPtr = 0;
1410 }
1411 }
1412
1413
1414 if (fc!=0)
1415 {
1416 c = FSOut1(FileByte);
1417 FileCRSend = (ts.TransBin==0) && (FileByte==0x0D);
1418 FileRetrySend = (c==0);
1419 if (FileRetrySend)
1420 {
1421 if (SendVar->ByteCount != BCOld)
1422 SendDlg->RefreshNum();
1423 return;
1424 }
1425 if (ts.LocalEcho>0)
1426 {
1427 c = FSEcho1(FileByte);
1428 FileRetryEcho = (c==0);
1429 if (FileRetryEcho)
1430 return;
1431 }
1432 }
1433 if ((fc==0) || ((SendVar->ByteCount % 100 == 0) && (FileBracketPtr == 0))) {
1434 SendDlg->RefreshNum();
1435 BCOld = SendVar->ByteCount;
1436 if (fc!=0)
1437 return;
1438 }
1439 } while (fc!=0);
1440
1441 FileTransEnd(OpSendFile);
1442 }
1443
1444 void FLogChangeButton(BOOL Pause)
1445 {
1446 if (FLogDlg!=NULL)
1447 FLogDlg->ChangeButton(Pause);
1448 }
1449
1450 void FLogRefreshNum()
1451 {
1452 if (FLogDlg!=NULL)
1453 FLogDlg->RefreshNum();
1454 }
1455
1456 BOOL OpenProtoDlg(PFileVar fv, int IdProto, int Mode, WORD Opt1, WORD Opt2)
1457 {
1458 int vsize;
1459 PProtoDlg pd;
1460
1461 ProtoId = IdProto;
1462
1463 switch (ProtoId) {
1464 case PROTO_KMT:
1465 vsize = sizeof(TKmtVar);
1466 break;
1467 case PROTO_XM:
1468 vsize = sizeof(TXVar);
1469 break;
1470 case PROTO_YM:
1471 vsize = sizeof(TYVar);
1472 break;
1473 case PROTO_ZM:
1474 vsize = sizeof(TZVar);
1475 break;
1476 case PROTO_BP:
1477 vsize = sizeof(TBPVar);
1478 break;
1479 case PROTO_QV:
1480 vsize = sizeof(TQVVar);
1481 break;
1482 }
1483 ProtoVar = (PCHAR)malloc(vsize);
1484 if (ProtoVar==NULL)
1485 return FALSE;
1486
1487 switch (ProtoId) {
1488 case PROTO_KMT:
1489 ((PKmtVar)ProtoVar)->KmtMode = Mode;
1490 break;
1491 case PROTO_XM:
1492 ((PXVar)ProtoVar)->XMode = Mode;
1493 ((PXVar)ProtoVar)->XOpt = Opt1;
1494 ((PXVar)ProtoVar)->TextFlag = 1 - (Opt2 & 1);
1495 break;
1496 case PROTO_YM:
1497 ((PYVar)ProtoVar)->YMode = Mode;
1498 ((PYVar)ProtoVar)->YOpt = Opt1;
1499 break;
1500 case PROTO_ZM:
1501 ((PZVar)ProtoVar)->BinFlag = (Opt1 & 1) != 0;
1502 ((PZVar)ProtoVar)->ZMode = Mode;
1503 break;
1504 case PROTO_BP:
1505 ((PBPVar)ProtoVar)->BPMode = Mode;
1506 break;
1507 case PROTO_QV:
1508 ((PQVVar)ProtoVar)->QVMode = Mode;
1509 break;
1510 }
1511
1512 pd = new CProtoDlg();
1513 if (pd==NULL)
1514 {
1515 free(ProtoVar);
1516 ProtoVar = NULL;
1517 return FALSE;
1518 }
1519 pd->Create(hInst, HVTWin, fv, &ts);
1520
1521 (*ProtoInit)(ProtoId,FileVar,ProtoVar,&cv,&ts);
1522
1523 PtDlg = pd;
1524 return TRUE;
1525 }
1526
1527 void CloseProtoDlg()
1528 {
1529 if (PtDlg!=NULL)
1530 {
1531 PtDlg->DestroyWindow();
1532 PtDlg = NULL;
1533
1534 ::KillTimer(FileVar->HMainWin,IdProtoTimer);
1535 if ((ProtoId==PROTO_QV) &&
1536 (((PQVVar)ProtoVar)->QVMode==IdQVSend))
1537 CommTextOut(&cv,"\015",1);
1538 if (FileVar->LogFlag)
1539 CloseHandle(FileVar->LogFile);
1540 FileVar->LogFile = 0;
1541 if (ProtoVar!=NULL)
1542 {
1543 free(ProtoVar);
1544 ProtoVar = NULL;
1545 }
1546 }
1547 }
1548
1549 BOOL ProtoStart()
1550 {
1551 if (cv.ProtoFlag)
1552 return FALSE;
1553 if (FSend)
1554 {
1555 FreeFileVar(&FileVar);
1556 return FALSE;
1557 }
1558
1559 if (! LoadTTFILE())
1560 return FALSE;
1561 NewFileVar(&FileVar);
1562
1563 if (FileVar==NULL)
1564 {
1565 FreeTTFILE();
1566 return FALSE;
1567 }
1568 cv.ProtoFlag = TRUE;
1569 return TRUE;
1570 }
1571
1572 void ProtoEnd()
1573 {
1574 if (! cv.ProtoFlag)
1575 return;
1576 cv.ProtoFlag = FALSE;
1577
1578 /* Enable transmit delay (serial port) */
1579 cv.DelayFlag = TRUE;
1580 TalkStatus = IdTalkKeyb;
1581
1582 CloseProtoDlg();
1583
1584 if ((FileVar!=NULL) && FileVar->Success)
1585 EndDdeCmnd(1);
1586 else
1587 EndDdeCmnd(0);
1588
1589 FreeTTFILE();
1590 FreeFileVar(&FileVar);
1591 }
1592
1593 int ProtoDlgParse()
1594 {
1595 int P;
1596
1597 P = ActiveWin;
1598 if (PtDlg==NULL)
1599 return P;
1600
1601 if ((*ProtoParse)(ProtoId,FileVar,ProtoVar,&cv))
1602 P = 0; /* continue */
1603 else {
1604 CommSend(&cv);
1605 ProtoEnd();
1606 }
1607 return P;
1608 }
1609
1610 void ProtoDlgTimeOut()
1611 {
1612 if (PtDlg!=NULL)
1613 (*ProtoTimeOutProc)(ProtoId,FileVar,ProtoVar,&cv);
1614 }
1615
1616 void ProtoDlgCancel()
1617 {
1618 if ((PtDlg!=NULL) &&
1619 (*ProtoCancel)(ProtoId,FileVar,ProtoVar,&cv))
1620 ProtoEnd();
1621 }
1622
1623 void KermitStart(int mode)
1624 {
1625 WORD w;
1626
1627 if (! ProtoStart())
1628 return;
1629
1630 switch (mode) {
1631 case IdKmtSend:
1632 FileVar->OpId = OpKmtSend;
1633 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1634 {
1635 if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_KERMIT,&w) ||
1636 (FileVar->NumFname==0))
1637 {
1638 ProtoEnd();
1639 return;
1640 }
1641 }
1642 else
1643 (*SetFileVar)(FileVar);
1644 break;
1645 case IdKmtReceive:
1646 FileVar->OpId = OpKmtRcv;
1647 break;
1648 case IdKmtGet:
1649 FileVar->OpId = OpKmtSend;
1650 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1651 {
1652 if (! (*GetGetFname)(FileVar->HMainWin,FileVar) ||
1653 (strlen(FileVar->FullName)==0))
1654 {
1655 ProtoEnd();
1656 return;
1657 }
1658 }
1659 else
1660 (*SetFileVar)(FileVar);
1661 break;
1662 case IdKmtFinish:
1663 FileVar->OpId = OpKmtFin;
1664 break;
1665 default:
1666 ProtoEnd();
1667 return;
1668 }
1669 TalkStatus = IdTalkQuiet;
1670
1671 /* disable transmit delay (serial port) */
1672 cv.DelayFlag = FALSE;
1673
1674 if (! OpenProtoDlg(FileVar,PROTO_KMT,mode,0,0))
1675 ProtoEnd();
1676 }
1677
1678 void XMODEMStart(int mode)
1679 {
1680 LONG Option;
1681 int tmp;
1682
1683 if (! ProtoStart())
1684 return;
1685
1686 if (mode==IdXReceive)
1687 FileVar->OpId = OpXRcv;
1688 else
1689 FileVar->OpId = OpXSend;
1690
1691 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1692 {
1693 Option = MAKELONG(ts.XmodemBin,ts.XmodemOpt);
1694 if (! (*GetXFname)(FileVar->HMainWin,
1695 mode==IdXReceive,&Option,FileVar,ts.FileDir))
1696 {
1697 ProtoEnd();
1698 return;
1699 }
1700 tmp = HIWORD(Option);
1701 if (mode == IdXReceive) {
1702 if (IsXoptCRC(tmp)) {
1703 if (IsXopt1k(ts.XmodemOpt)) {
1704 ts.XmodemOpt = Xopt1kCRC;
1705 }
1706 else {
1707 ts.XmodemOpt = XoptCRC;
1708 }
1709 }
1710 else {
1711 if (IsXopt1k(ts.XmodemOpt)) {
1712 ts.XmodemOpt = Xopt1kCksum;
1713 }
1714 else {
1715 ts.XmodemOpt = XoptCheck;
1716 }
1717 }
1718 ts.XmodemBin = LOWORD(Option);
1719 }
1720 else {
1721 if (IsXopt1k(tmp)) {
1722 if (IsXoptCRC(ts.XmodemOpt)) {
1723 ts.XmodemOpt = Xopt1kCRC;
1724 }
1725 else {
1726 ts.XmodemOpt = Xopt1kCksum;
1727 }
1728 }
1729 else {
1730 if (IsXoptCRC(ts.XmodemOpt)) {
1731 ts.XmodemOpt = XoptCRC;
1732 }
1733 else {
1734 ts.XmodemOpt = XoptCheck;
1735 }
1736 }
1737 }
1738 }
1739 else
1740 (*SetFileVar)(FileVar);
1741
1742 if (mode==IdXReceive)
1743 FileVar->FileHandle = _lcreat(FileVar->FullName,0);
1744 else
1745 FileVar->FileHandle = _lopen(FileVar->FullName,OF_READ);
1746
1747 FileVar->FileOpen = FileVar->FileHandle != INVALID_HANDLE_VALUE;
1748 if (! FileVar->FileOpen)
1749 {
1750 ProtoEnd();
1751 return;
1752 }
1753 TalkStatus = IdTalkQuiet;
1754
1755 /* disable transmit delay (serial port) */
1756 cv.DelayFlag = FALSE;
1757
1758 if (! OpenProtoDlg(FileVar,PROTO_XM,mode,
1759 ts.XmodemOpt,ts.XmodemBin))
1760 ProtoEnd();
1761 }
1762
1763 void YMODEMStart(int mode)
1764 {
1765 WORD Opt;
1766
1767 if (! ProtoStart())
1768 return;
1769
1770 if (mode==IdYSend)
1771 {
1772 // �t�@�C���]�������I�v�V������"Yopt1K"�����������B
1773 // TODO: "Yopt1K", "YoptG", "YoptSingle"�������������������AIDD_FOPT���g�������K�v�����B
1774 Opt = Yopt1K;
1775 FileVar->OpId = OpYSend;
1776 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1777 {
1778 if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_Y,&Opt) ||
1779 (FileVar->NumFname==0))
1780 {
1781 ProtoEnd();
1782 return;
1783 }
1784 //ts.XmodemBin = Opt;
1785 }
1786 else
1787 (*SetFileVar)(FileVar);
1788 }
1789 else {
1790 FileVar->OpId = OpYRcv;
1791 // �t�@�C���]�������I�v�V������"Yopt1K"�����������B
1792 Opt = Yopt1K;
1793 (*SetFileVar)(FileVar);
1794 }
1795
1796 TalkStatus = IdTalkQuiet;
1797
1798 /* disable transmit delay (serial port) */
1799 cv.DelayFlag = FALSE;
1800
1801 if (! OpenProtoDlg(FileVar,PROTO_YM,mode,Opt,0))
1802 ProtoEnd();
1803 }
1804
1805 void ZMODEMStart(int mode)
1806 {
1807 WORD Opt;
1808
1809 if (! ProtoStart())
1810 return;
1811
1812 if (mode == IdZSend || mode == IdZAutoS)
1813 {
1814 Opt = ts.XmodemBin;
1815 FileVar->OpId = OpZSend;
1816 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1817 {
1818 if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_Z,&Opt) ||
1819 (FileVar->NumFname==0))
1820 {
1821 if (mode == IdZAutoS) {
1822 CommRawOut(&cv, "\030\030\030\030\030\030\030\030\b\b\b\b\b\b\b\b\b\b", 18);
1823 }
1824 ProtoEnd();
1825 return;
1826 }
1827 ts.XmodemBin = Opt;
1828 }
1829 else
1830 (*SetFileVar)(FileVar);
1831 }
1832 else /* IdZReceive or IdZAutoR */
1833 FileVar->OpId = OpZRcv;
1834
1835 TalkStatus = IdTalkQuiet;
1836
1837 /* disable transmit delay (serial port) */
1838 cv.DelayFlag = FALSE;
1839
1840 if (! OpenProtoDlg(FileVar,PROTO_ZM,mode,Opt,0))
1841 ProtoEnd();
1842 }
1843
1844 void BPStart(int mode)
1845 {
1846 LONG Option = 0;
1847
1848 if (! ProtoStart())
1849 return;
1850 if (mode==IdBPSend)
1851 {
1852 FileVar->OpId = OpBPSend;
1853 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1854 {
1855 FileVar->FullName[0] = 0;
1856 if (! (*GetTransFname)(FileVar, ts.FileDir, GTF_BP, &Option))
1857 {
1858 ProtoEnd();
1859 return;
1860 }
1861 }
1862 else
1863 (*SetFileVar)(FileVar);
1864 }
1865 else /* IdBPReceive or IdBPAuto */
1866 FileVar->OpId = OpBPRcv;
1867
1868 TalkStatus = IdTalkQuiet;
1869
1870 /* disable transmit delay (serial port) */
1871 cv.DelayFlag = FALSE;
1872
1873 if (! OpenProtoDlg(FileVar,PROTO_BP,mode,0,0))
1874 ProtoEnd();
1875 }
1876
1877 void QVStart(int mode)
1878 {
1879 WORD W;
1880
1881 if (! ProtoStart())
1882 return;
1883
1884 if (mode==IdQVSend)
1885 {
1886 FileVar->OpId = OpQVSend;
1887 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1888 {
1889 if (! (*GetMultiFname)(FileVar,ts.FileDir,GMF_QV, &W) ||
1890 (FileVar->NumFname==0))
1891 {
1892 ProtoEnd();
1893 return;
1894 }
1895 }
1896 else
1897 (*SetFileVar)(FileVar);
1898 }
1899 else
1900 FileVar->OpId = OpQVRcv;
1901
1902 TalkStatus = IdTalkQuiet;
1903
1904 /* disable transmit delay (serial port) */
1905 cv.DelayFlag = FALSE;
1906
1907 if (! OpenProtoDlg(FileVar,PROTO_QV,mode,0,0))
1908 ProtoEnd();
1909 }

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