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 6489 - (show annotations) (download) (as text)
Fri Sep 23 13:12:44 2016 UTC (7 years, 6 months ago) by yutakapon
Original Path: trunk/teraterm/teraterm/filesys.cpp
File MIME type: text/x-c++src
File size: 44703 byte(s)
チケット #36655 ログファイルオープンエラー

DeferredLogWriteMode=on の場合において、ログファイルのオープン後、
すぐにクローズを行うと、まれに Tera Term がデッドロックしてストールするという
問題を修正した。

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

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