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 8897 - (show annotations) (download) (as text)
Tue Aug 18 15:27:54 2020 UTC (3 years, 7 months ago) by zmatsuo
File MIME type: text/x-c++src
File size: 40977 byte(s)
ログに関するコードを filesys_log.c に移動した

- ログ用構造体(TFileVar_#filesys_log.c)から不要メンバ削除
- OnCommOpen()#vtwin.cpp で log,dde(macro)用バッファを作成していたが、作成済みのため削除
1 /*
2 * (C) 2020 TeraTerm Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /* TERATERM.EXE, log routines */
30 #include <stdio.h>
31 #include <io.h>
32 #include <process.h>
33 #include <windows.h>
34 #include <htmlhelp.h>
35 #include <assert.h>
36
37 #include "teraterm.h"
38 #include "tttypes.h"
39 #include "ttftypes.h"
40 #include "ftdlg.h"
41 #include "ttwinman.h"
42 #include "commlib.h"
43 #include "ttcommon.h"
44 #include "ttlib.h"
45 #include "dlglib.h"
46 #include "vtterm.h"
47 #include "ftlib.h"
48 #include "buffer.h"
49 #include "helpid.h"
50 #include "layer_for_unicode.h"
51 #include "layer_for_unicode_crt.h"
52 #include "codeconv.h"
53
54 #include "filesys_log_res.h"
55 #include "filesys.h"
56
57 typedef struct {
58 char FullName[MAX_PATH];
59 int DirLen;
60
61 BOOL FileOpen;
62 HANDLE FileHandle;
63 LONG FileSize, ByteCount;
64 BOOL OverWrite;
65
66 BOOL Success;
67 BOOL NoMsg;
68
69 char LogDefaultPath[MAX_PATH];
70 BOOL HideDialog;
71
72 DWORD StartTime;
73
74 // log rotate
75 int RotateMode; // enum rotate_mode RotateMode;
76 LONG RotateSize;
77 int RotateStep;
78
79 HANDLE LogThread;
80 DWORD LogThreadId;
81 HANDLE LogThreadEvent;
82 } TFileVar_;
83 typedef TFileVar_ *PFileVar_;
84
85 #define PFileVar PFileVar_
86 #define TFileVar TFileVar_
87
88 static PFileVar LogVar = NULL;
89
90 BOOL FileLog = FALSE;
91 BOOL BinLog = FALSE;
92
93 /*
94 Line Head flag for timestamping
95 2007.05.24 Gentaro
96 */
97 enum enumLineEnd {
98 Line_Other = 0,
99 Line_LineHead = 1,
100 Line_FileHead = 2,
101 };
102
103 static enum enumLineEnd eLineEnd = Line_LineHead;
104
105
106 // �x�����������p�X���b�h�����b�Z�[�W
107 #define WM_DPC_LOGTHREAD_SEND (WM_APP + 1)
108
109 static void FileTransEnd_(void);
110 static void Log1Bin(BYTE b);
111 static void LogBinSkip(int add);
112 static BOOL CreateLogBuf(void);
113 static BOOL CreateBinBuf(void);
114
115 static PFileTransDlg FLogDlg = NULL;
116
117 static BOOL OpenFTDlg_(PFileVar fv)
118 {
119 PFileTransDlg FTDlg;
120
121 FTDlg = new CFileTransDlg();
122
123 fv->StartTime = 0;
124 cv.FilePause &= ~OpLog;
125
126 if (ts.LogHideDialog)
127 fv->HideDialog = TRUE;
128
129 if (FTDlg!=NULL)
130 {
131 char DlgCaption[40];
132 strncpy_s(DlgCaption, _countof(DlgCaption),"Tera Term: ", _TRUNCATE);
133 char uimsg[MAX_UIMSG];
134 get_lang_msg("FILEDLG_TRANS_TITLE_LOG", uimsg, sizeof(uimsg), TitLog, ts.UILanguageFile);
135 strncat_s(DlgCaption, _countof(DlgCaption), uimsg, _TRUNCATE);
136
137 CFileTransDlgInfo info;
138 info.UILanguageFile = ts.UILanguageFile;
139 info.OpId = OpLog;
140 info.DlgCaption = DlgCaption;
141 info.FileName = &fv->FullName[fv->DirLen];
142 info.FullName = fv->FullName;
143 info.HideDialog = fv->HideDialog;
144 info.HMainWin = HVTWin;
145 FTDlg->Create(hInst, &info);
146 FTDlg->RefreshNum(fv->StartTime, fv->FileSize, fv->ByteCount);
147 }
148
149 FLogDlg = FTDlg; /* Log */
150
151 fv->StartTime = GetTickCount();
152
153 return (FTDlg!=NULL);
154 }
155
156 /**
157 * �t�@�C�������������u������
158 * &h �z�X�g�����u�� (2007.5.14)
159 * &p TCP�|�[�g�������u�� (2009.6.12)
160 * &u ���O�I���������[�U��
161 */
162 static void ConvertLogname(char *c, int destlen)
163 {
164 char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
165 char tmphost[1024];
166 char tmpuser[256+1];
167 DWORD len_user = sizeof(tmpuser);
168
169 memset(buf, 0, sizeof(buf));
170
171 while(*p != '\0') {
172 if (*p == '&' && *(p+1) != '\0') {
173 switch (*(p+1)) {
174 case 'h':
175 if (cv.Open) {
176 if (cv.PortType == IdTCPIP) {
177 // �z�X�g����IPv6�A�h���X�����A�t�@�C�������g�p�����������������������A
178 // �]�v�����������������B
179 // (2013.3.9 yutaka)
180 strncpy_s(tmphost, sizeof(tmphost), ts.HostName, _TRUNCATE);
181 //strncpy_s(tmphost, sizeof(tmphost), "2001:0db8:bd05:01d2:288a:1fc0:0001:10ee", _TRUNCATE);
182 replaceInvalidFileNameChar(tmphost, '_');
183 strncat_s(buf,sizeof(buf), tmphost, _TRUNCATE);
184 }
185 else if (cv.PortType == IdSerial) {
186 strncpy_s(buf2,sizeof(buf2),buf,_TRUNCATE);
187 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%sCOM%d", buf2, ts.ComPort);
188 }
189 }
190 break;
191 case 'p':
192 if (cv.Open) {
193 if (cv.PortType == IdTCPIP) {
194 char port[6];
195 _snprintf_s(port, sizeof(port), _TRUNCATE, "%d", ts.TCPPort);
196 strncat_s(buf,sizeof(buf),port,_TRUNCATE);
197 }
198 }
199 break;
200 case 'u':
201 if (GetUserName(tmpuser, &len_user) != 0) {
202 strncat_s(buf,sizeof(buf),tmpuser,_TRUNCATE);
203 }
204 break;
205 default:
206 strncpy_s(buf2,sizeof(buf2),p,2);
207 strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
208 }
209 p++;
210 }
211 else {
212 strncpy_s(buf2,sizeof(buf2),p,1);
213 strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
214 }
215 p++;
216 }
217 strncpy_s(c, destlen, buf, _TRUNCATE);
218 }
219
220 static void FixLogOption(void)
221 {
222 if (ts.LogBinary) {
223 ts.LogTypePlainText = false;
224 ts.LogTimestamp = false;
225 }
226 }
227
228
229 // �X���b�h���I�����t�@�C�����N���[�Y
230 static void CloseFileSync(PFileVar ptr)
231 {
232 BOOL ret;
233
234 if (!ptr->FileOpen)
235 return;
236
237 if (ptr->LogThread != INVALID_HANDLE_VALUE) {
238 // �X���b�h���I������
239 ret = PostThreadMessage(ptr->LogThreadId, WM_QUIT, 0, 0);
240 if (ret != 0) {
241 // �X���b�h�L���[���G���L���[���������������������������s���B
242 WaitForSingleObject(ptr->LogThread, INFINITE);
243 }
244 else {
245 //DWORD code = GetLastError();
246 }
247 CloseHandle(ptr->LogThread);
248 ptr->LogThread = INVALID_HANDLE_VALUE;
249 }
250 CloseHandle(ptr->FileHandle);
251 }
252
253 // �x�����������p�X���b�h
254 static unsigned _stdcall DeferredLogWriteThread(void *arg)
255 {
256 MSG msg;
257 PFileVar fv = (PFileVar)arg;
258 PCHAR buf;
259 DWORD buflen;
260 DWORD wrote;
261
262 PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
263
264 // �X���b�h�L���[���������I�������������X���b�h�����������m�����B
265 if (fv->LogThreadEvent != NULL) {
266 SetEvent(fv->LogThreadEvent);
267 }
268
269 while (GetMessage(&msg, NULL, 0, 0) > 0) {
270 switch (msg.message) {
271 case WM_DPC_LOGTHREAD_SEND:
272 buf = (PCHAR)msg.wParam;
273 buflen = (DWORD)msg.lParam;
274 WriteFile(LogVar->FileHandle, buf, buflen, &wrote, NULL);
275 free(buf); // ����������������
276 break;
277
278 case WM_QUIT:
279 goto end;
280 break;
281 }
282 }
283
284 end:
285 _endthreadex(0);
286 return (0);
287 }
288
289 /**
290 * �_�C�A���O�����e�� ts ����������
291 *
292 * TODO
293 * �_�C�A���O�����������l�������I��������
294 * ����������������������������������������������?
295 */
296 static void SetLogFlags(HWND Dialog)
297 {
298 WORD BinFlag, val;
299
300 GetRB(Dialog, &BinFlag, IDC_FOPTBIN, IDC_FOPTBIN);
301 ts.LogBinary = BinFlag;
302
303 GetRB(Dialog, &val, IDC_APPEND, IDC_APPEND);
304 ts.Append = val;
305
306 if (!BinFlag) {
307 GetRB(Dialog, &val, IDC_PLAINTEXT, IDC_PLAINTEXT);
308 ts.LogTypePlainText = val;
309
310 GetRB(Dialog, &val, IDC_TIMESTAMP, IDC_TIMESTAMP);
311 ts.LogTimestamp = val;
312 }
313
314 GetRB(Dialog, &val, IDC_HIDEDIALOG, IDC_HIDEDIALOG);
315 ts.LogHideDialog = val;
316
317 GetRB(Dialog, &val, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST);
318 ts.LogAllBuffIncludedInFirst = val;
319
320 ts.LogTimestampType = (GetCurSel(Dialog, IDC_TIMESTAMPTYPE) - 1);
321 }
322
323 /**
324 * ���O�t�@�C���`�F�b�N
325 *
326 * @param[in] filename
327 * @param[out] exist TURE/FALSE
328 * @param[out] bom 0 no BOM (or file not exist)
329 * 1 UTF-8
330 * 2 UTF-16LE
331 * 3 UTF-16BE
332 */
333 static void CheckLogFile(const wchar_t *filename, BOOL *exist, int *bom)
334 {
335 *exist = FALSE;
336 *bom = 0;
337
338 // �t�@�C������������?
339 DWORD logdir = _GetFileAttributesW(filename);
340 if ((logdir != INVALID_FILE_ATTRIBUTES) && ((logdir & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
341 // �t�@�C����������
342 *exist = TRUE;
343
344 // BOM�L��/�����`�F�b�N
345 FILE *fp = __wfopen(filename, L"rb");
346 if (fp != NULL) {
347 unsigned char tmp[4];
348 size_t l = fread(tmp, 1, sizeof(tmp), fp);
349 fclose(fp);
350 if (l < 2) {
351 *bom = 0;
352 } else if (l >= 2 && tmp[0] == 0xff && tmp[1] == 0xfe) {
353 // UTF-16LE
354 *bom = 2;
355 } else if (l >= 2 && tmp[0] == 0xfe && tmp[1] == 0xff) {
356 // UTF-16BE
357 *bom = 3;
358 } else if (l >= 3 && tmp[0] == 0xef && tmp[1] == 0xbb && tmp[2] == 0xbf) {
359 // UTF-8
360 *bom = 1;
361 } else {
362 *bom = 0;
363 }
364 }
365 }
366 }
367
368 typedef struct {
369 FLogDlgInfo_t *info;
370 // work
371 BOOL file_exist;
372 int current_bom;
373 TTTSet *pts;
374 } LogDlgWork_t;
375
376 static void ArrangeControls(HWND Dialog, LogDlgWork_t *work)
377 {
378 if (work->file_exist) {
379 EnableWindow(GetDlgItem(Dialog, IDC_APPEND), TRUE);
380 if (work->pts->Append > 0) {
381 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_APPEND);
382 }
383 }
384 else {
385 // �t�@�C�������� -> �V�K
386 EnableWindow(GetDlgItem(Dialog, IDC_APPEND), FALSE);
387 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_NEW_OVERWRITE);
388 }
389
390 if (work->file_exist && IsDlgButtonChecked(Dialog, IDC_APPEND) == BST_CHECKED) {
391 // �t�@�C������������ && append
392 int bom = work->current_bom;
393 if (bom != 0) {
394 // BOM�L��
395 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
396 int cur =
397 bom == 1 ? 0 :
398 bom == 2 ? 1 :
399 bom == 3 ? 2 : 0;
400 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, cur, 0);
401 }
402 else {
403 // BOM����
404 CheckDlgButton(Dialog, IDC_BOM, BST_UNCHECKED);
405 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
406 }
407 if (IsDlgButtonChecked(Dialog, IDC_FOPTTEXT) == BST_CHECKED) {
408 EnableWindow(GetDlgItem(Dialog, IDC_BOM), FALSE);
409 if (bom != 0) {
410 // BOM�L��
411 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), FALSE);
412 }
413 else {
414 // BOM����
415 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), TRUE);
416 }
417 }
418 }
419 else {
420 // �t�@�C�������� ���� append��������(������)
421 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_NEW_OVERWRITE);
422 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
423 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
424 if (IsDlgButtonChecked(Dialog, IDC_FOPTTEXT) == BST_CHECKED) {
425 EnableWindow(GetDlgItem(Dialog, IDC_BOM), TRUE);
426 }
427 }
428 }
429
430 static void CheckLogFile(HWND Dialog, const wchar_t *filename, LogDlgWork_t *work)
431 {
432 BOOL exist;
433 int bom;
434 CheckLogFile(filename, &exist, &bom);
435 work->file_exist = exist;
436 work->current_bom = bom;
437 ArrangeControls(Dialog, work);
438 }
439
440 static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam)
441 {
442 static const DlgTextInfo TextInfos[] = {
443 { 0, "DLG_TABSHEET_TITLE_LOG" },
444 { IDC_FOPTBIN, "DLG_FOPT_BINARY" },
445 { IDC_APPEND, "DLG_FOPT_APPEND" },
446 { IDC_PLAINTEXT, "DLG_FOPT_PLAIN" },
447 { IDC_HIDEDIALOG, "DLG_FOPT_HIDEDIALOG" },
448 { IDC_ALLBUFF_INFIRST, "DLG_FOPT_ALLBUFFINFIRST" },
449 { IDC_TIMESTAMP, "DLG_FOPT_TIMESTAMP" },
450 };
451 static const I18nTextInfo timestamp_list[] = {
452 { "DLG_FOPT_TIMESTAMP_LOCAL", L"Local Time" },
453 { "DLG_FOPT_TIMESTAMP_UTC", L"UTC" },
454 { "DLG_FOPT_TIMESTAMP_ELAPSED_LOGGING", L"Elapsed Time (Logging)" },
455 { "DLG_FOPT_TIMESTAMP_ELAPSED_CONNECTION", L"Elapsed Time (Connection)" },
456 };
457 LogDlgWork_t *work = (LogDlgWork_t *)GetWindowLongPtr(Dialog, DWLP_USER);
458
459 if (Message == RegisterWindowMessage(HELPMSGSTRING)) {
460 // �R�����_�C�A���O�������w���v���b�Z�[�W���t��������
461 Message = WM_COMMAND;
462 wParam = IDHELP;
463 }
464 switch (Message) {
465 case WM_INITDIALOG: {
466 work = (LogDlgWork_t *)lParam;
467 TTTSet *pts = work->pts;
468 const char *UILanguageFile = pts->UILanguageFile;
469 SetWindowLongPtr(Dialog, DWLP_USER, (LONG_PTR)work);
470 ::DragAcceptFiles(Dialog, TRUE);
471
472 SetDlgTexts(Dialog, TextInfos, _countof(TextInfos), UILanguageFile);
473 SetI18nList("Tera Term", Dialog, IDC_TIMESTAMPTYPE, timestamp_list, _countof(timestamp_list),
474 UILanguageFile, 0);
475
476 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-8");
477 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-16LE");
478 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-16BE");
479 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
480
481 _SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, work->info->filename);
482 work->info->filename = NULL;
483
484 // Binary/Text �`�F�b�N�{�b�N�X
485 if (pts->LogBinary) {
486 CheckRadioButton(Dialog, IDC_FOPTBIN, IDC_FOPTTEXT, IDC_FOPTBIN);
487 }
488 else {
489 CheckRadioButton(Dialog, IDC_FOPTBIN, IDC_FOPTTEXT, IDC_FOPTTEXT);
490 }
491
492 // Plain Text �`�F�b�N�{�b�N�X
493 if (pts->LogBinary) {
494 // Binary�t���O���L�����������`�F�b�N��������
495 DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_PLAINTEXT);
496 }
497 else if (pts->LogTypePlainText) {
498 SetRB(Dialog, 1, IDC_PLAINTEXT, IDC_PLAINTEXT);
499 }
500
501 // Hide dialog�`�F�b�N�{�b�N�X (2008.1.30 maya)
502 if (pts->LogHideDialog) {
503 SetRB(Dialog, 1, IDC_HIDEDIALOG, IDC_HIDEDIALOG);
504 }
505
506 // Include screen buffer�`�F�b�N�{�b�N�X (2013.9.29 yutaka)
507 if (pts->LogAllBuffIncludedInFirst) {
508 SetRB(Dialog, 1, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST);
509 }
510
511 // timestamp�`�F�b�N�{�b�N�X (2006.7.23 maya)
512 if (pts->LogBinary) {
513 // Binary�t���O���L�����������`�F�b�N��������
514 DisableDlgItem(Dialog, IDC_TIMESTAMP, IDC_TIMESTAMP);
515 }
516 else if (pts->LogTimestamp) {
517 SetRB(Dialog, 1, IDC_TIMESTAMP, IDC_TIMESTAMP);
518 }
519
520 // timestamp ����
521 int tstype = pts->LogTimestampType == TIMESTAMP_LOCAL ? 0 :
522 pts->LogTimestampType == TIMESTAMP_UTC ? 1 :
523 pts->LogTimestampType == TIMESTAMP_ELAPSED_LOGSTART ? 2 :
524 pts->LogTimestampType == TIMESTAMP_ELAPSED_CONNECTED ? 3 : 0;
525 SendDlgItemMessage(Dialog, IDC_TIMESTAMPTYPE, CB_SETCURSEL, tstype, 0);
526 if (pts->LogBinary || !pts->LogTimestamp) {
527 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
528 }
529
530 CenterWindow(Dialog, GetParent(Dialog));
531
532 return TRUE;
533 }
534
535 case WM_COMMAND:
536 switch (LOWORD(wParam)) {
537 case IDOK: {
538 wchar_t filename[MAX_PATH];
539 _GetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
540 work->info->filename = _wcsdup(filename);
541 work->info->append = IsDlgButtonChecked(Dialog, IDC_APPEND) == BST_CHECKED;
542 work->info->bom = IsDlgButtonChecked(Dialog, IDC_BOM) == BST_CHECKED;
543 work->info->code = (int)SendDlgItemMessageA(Dialog, IDC_TEXTCODING_DROPDOWN, CB_GETCURSEL, 0, 0);
544 SetLogFlags(Dialog);
545 EndDialog(Dialog, IDOK);
546 break;
547 }
548 case IDCANCEL:
549 EndDialog(Dialog, IDCANCEL);
550 break;
551 case IDHELP:
552 OpenHelp(HH_HELP_CONTEXT, HlpFileLog, work->pts->UILanguageFile);
553 break;
554 case IDC_FOPT_FILENAME_BUTTON: {
555 /* save current dir */
556 const char *UILanguageFile = work->pts->UILanguageFile;
557 wchar_t curdir[MAXPATHLEN];
558 _GetCurrentDirectoryW(_countof(curdir), curdir);
559
560 wchar_t fname[MAX_PATH];
561 GetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, fname, _countof(fname));
562
563 wchar_t FNFilter[128*3];
564 get_lang_msgW("FILEDLG_ALL_FILTER", FNFilter, sizeof(FNFilter), L"All(*.*)\\0*.*\\0\\0", UILanguageFile);
565
566 wchar_t caption[MAX_PATH];
567 wchar_t uimsg[MAX_UIMSG];
568 #define TitLogW L"Log"
569 get_lang_msgW("FILEDLG_TRANS_TITLE_LOG", uimsg, _countof(uimsg), TitLogW, UILanguageFile);
570 wcsncpy_s(caption, _countof(caption), L"Tera Term: ", _TRUNCATE);
571 wcsncat_s(caption, _countof(caption), uimsg, _TRUNCATE);
572
573 OPENFILENAMEW ofn = {};
574 ofn.lStructSize = get_OPENFILENAME_SIZEW();
575 //ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
576 ofn.Flags |= OFN_EXPLORER | OFN_ENABLESIZING;
577 ofn.Flags |= OFN_SHOWHELP;
578 ofn.Flags |= OFN_NOCHANGEDIR; // ��������������������������������
579 ofn.hwndOwner = Dialog;
580 ofn.lpstrFilter = FNFilter;
581 ofn.nFilterIndex = 1;
582 ofn.lpstrFile = fname;
583 ofn.nMaxFile = _countof(fname);
584 ofn.lpstrTitle = caption;
585 BOOL Ok = GetSaveFileNameW(&ofn);
586 if (Ok) {
587 SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, fname);
588 }
589
590 /* restore dir */
591 _SetCurrentDirectoryW(curdir);
592
593 break;
594 }
595 case IDC_FOPTBIN:
596 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), FALSE);
597 EnableWindow(GetDlgItem(Dialog, IDC_BOM), FALSE);
598 DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_TIMESTAMP);
599 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
600 break;
601 case IDC_FOPTTEXT:
602 ArrangeControls(Dialog, work);
603 EnableDlgItem(Dialog, IDC_PLAINTEXT, IDC_TIMESTAMP);
604 // FALLTHROUGH -- BinFlag �� off ������ Timestamp �������L��/��������������
605 case IDC_TIMESTAMP:
606 if (IsDlgButtonChecked(Dialog, IDC_TIMESTAMP) == BST_CHECKED) {
607 EnableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
608 }
609 else {
610 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
611 }
612 break;
613 case IDC_FOPT_FILENAME_EDIT:
614 if (HIWORD(wParam) == EN_CHANGE){
615 wchar_t filename[MAX_PATH];
616 GetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
617 CheckLogFile(Dialog, filename, work);
618 }
619 break;
620 case IDC_NEW_OVERWRITE:
621 if (IsDlgButtonChecked(Dialog, IDC_FOPTTEXT) == BST_CHECKED) {
622 EnableWindow(GetDlgItem(Dialog, IDC_BOM), TRUE);
623 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), TRUE);
624 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
625 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
626 }
627 break;
628 case IDC_APPEND:
629 ArrangeControls(Dialog, work);
630 break;
631 }
632 break;
633 case WM_DROPFILES: {
634 // �����h���b�v��������������1������������
635 HDROP hDrop = (HDROP)wParam;
636 const UINT len = _DragQueryFileW(hDrop, 0, NULL, 0);
637 if (len == 0) {
638 DragFinish(hDrop);
639 return TRUE;
640 }
641 wchar_t *filename = (wchar_t *)malloc(sizeof(wchar_t) * (len + 1));
642 _DragQueryFileW(hDrop, 0, filename, len + 1);
643 filename[len] = '\0';
644 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_APPEND);
645 _SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename);
646 SendDlgItemMessage(Dialog, IDC_FOPT_FILENAME_EDIT, EM_SETSEL, len, len);
647 free(filename);
648 DragFinish(hDrop);
649 return TRUE;
650 }
651 }
652 return FALSE;
653 }
654
655 static BOOL LogStart(const char *fname)
656 {
657 unsigned tid;
658
659 strncpy_s(LogVar->FullName, sizeof(LogVar->FullName), fname, _TRUNCATE);
660
661 if (! LoadTTFILE()) return FALSE;
662
663 //(*SetFileVar)(LogVar);
664 {
665 int i;
666 char c;
667 PFileVar fv = LogVar;
668 GetFileNamePos(fv->FullName,&(fv->DirLen),&i);
669 c = fv->FullName[fv->DirLen];
670 if (c=='\\'||c=='/') fv->DirLen++;
671 }
672 FixLogOption();
673
674 if (ts.LogBinary > 0)
675 {
676 BinLog = TRUE;
677 FileLog = FALSE;
678 if (! CreateBinBuf())
679 {
680 FileTransEnd_();
681 return FALSE;
682 }
683 }
684 else {
685 BinLog = FALSE;
686 FileLog = TRUE;
687 if (! CreateLogBuf())
688 {
689 FileTransEnd_();
690 return FALSE;
691 }
692 }
693 cv.LStart = cv.LogPtr;
694 cv.LCount = 0;
695
696 /* 2007.05.24 Gentaro */
697 eLineEnd = Line_LineHead;
698
699 if (ts.Append > 0)
700 {
701 int dwShareMode = FILE_SHARE_READ;
702 if (!ts.LogLockExclusive) {
703 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
704 }
705 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
706 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
707 if (LogVar->FileHandle != INVALID_HANDLE_VALUE){
708 SetFilePointer(LogVar->FileHandle, 0, NULL, FILE_END);
709 /* 2007.05.24 Gentaro
710 If log file already exists,
711 a newline is inserted before the first timestamp.
712 */
713 eLineEnd = Line_FileHead;
714 }
715 }
716 else {
717 int dwShareMode = FILE_SHARE_READ;
718 if (!ts.LogLockExclusive) {
719 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
720 }
721 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
722 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
723 }
724 LogVar->FileOpen = (LogVar->FileHandle != INVALID_HANDLE_VALUE);
725 if (! LogVar->FileOpen)
726 {
727 char msg[128];
728
729 // �t�@�C���I�[�v���G���[�������b�Z�[�W�\�������������B(2008.7.9 yutaka)
730 if (LogVar->NoMsg == FALSE) {
731 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Can not create a `%s' file. (%d)", LogVar->FullName, GetLastError());
732 MessageBox(NULL, msg, "Tera Term: File open error", MB_OK | MB_ICONERROR);
733 }
734
735 FileTransEnd_();
736 return FALSE;
737 }
738 LogVar->ByteCount = 0;
739
740 // Log rotate configuration
741 LogVar->RotateMode = ts.LogRotate;
742 LogVar->RotateSize = ts.LogRotateSize;
743 LogVar->RotateStep = ts.LogRotateStep;
744
745 // Log rotate���L���������A�����t�@�C���T�C�Y�����������B
746 // �������t�@�C�������������T�C�Y�����[�e�[�g�������������C���B
747 // (2016.4.9 yutaka)
748 if (LogVar->RotateMode != ROTATE_NONE) {
749 DWORD size = GetFileSize(LogVar->FileHandle, NULL);
750 if (size != -1)
751 LogVar->ByteCount = size;
752 }
753
754 if (! OpenFTDlg_(LogVar)) {
755 FileTransEnd_();
756 return FALSE;
757 }
758
759 // �x�����������p�X���b�h���N�����B
760 // (2013.4.19 yutaka)
761 // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
762 // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
763 // �����������������C�������B
764 // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
765 // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
766 // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
767 // (2016.9.23 yutaka)
768 LogVar->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
769 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
770 LogVar->LogThreadId = tid;
771 if (LogVar->LogThreadEvent != NULL) {
772 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
773 CloseHandle(LogVar->LogThreadEvent);
774 }
775
776 // �����o�b�t�@�������f�[�^�������������o���������A
777 // ���O�������J�n�����B
778 // (2013.9.29 yutaka)
779 if (ts.LogAllBuffIncludedInFirst) {
780 DWORD ofs, size, written_size;
781 char buf[512];
782 const char *crlf = "\r\n";
783 DWORD crlf_len = 2;
784 for (ofs = 0 ; ; ofs++ ) {
785 // 1�����s�����������B���������������A�G�X�P�[�v�V�[�P���X�������������B
786 size = BuffGetAnyLineData(ofs, buf, sizeof(buf));
787 if (size == -1)
788 break;
789
790 #if 0
791 if (ts.DeferredLogWriteMode) { // �x����������
792 char *pbuf = (char *)malloc(size + 2);
793 memcpy(pbuf, buf, size);
794 pbuf[size] = '\r';
795 pbuf[size+1] = '\n';
796 Sleep(1); // �X���b�h�L���[�����������������A�R���e�L�X�g�X�C�b�`�������B
797 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)pbuf, size + 2);
798 } else { // �������B�l�b�g���[�N�o�R�����x���B
799 #endif
800 WriteFile(LogVar->FileHandle, buf, size, &written_size, NULL);
801 WriteFile(LogVar->FileHandle, crlf, crlf_len, &written_size, NULL);
802 #if 0
803 }
804 #endif
805 }
806 }
807
808 if (FileLog) {
809 cv.Log1Byte = LogPut1;
810 }
811 if (BinLog) {
812 cv.Log1Bin = Log1Bin;
813 cv.LogBinSkip = LogBinSkip;
814 }
815
816 return TRUE;
817 }
818
819 /**
820 * ���O��1byte��������
821 * �o�b�t�@��������������
822 * ���������������� LogToFile() ���s������
823 */
824 void LogPut1(BYTE b)
825 {
826 cv.LogBuf[cv.LogPtr] = b;
827 cv.LogPtr++;
828 if (cv.LogPtr>=InBuffSize)
829 cv.LogPtr = cv.LogPtr-InBuffSize;
830
831 if (FileLog)
832 {
833 if (cv.LCount>=InBuffSize)
834 {
835 cv.LCount = InBuffSize;
836 cv.LStart = cv.LogPtr;
837 }
838 else
839 cv.LCount++;
840 }
841 else
842 cv.LCount = 0;
843 }
844
845 static BOOL Get1(PCHAR Buf, int *Start, int *Count, PBYTE b)
846 {
847 if (*Count<=0) return FALSE;
848 *b = Buf[*Start];
849 (*Start)++;
850 if (*Start>=InBuffSize)
851 *Start = *Start-InBuffSize;
852 (*Count)--;
853 return TRUE;
854 }
855
856
857
858 static CRITICAL_SECTION g_filelog_lock; /* ���b�N�p���� */
859
860 void logfile_lock_initialize(void)
861 {
862 InitializeCriticalSection(&g_filelog_lock);
863 }
864
865 static inline void logfile_lock(void)
866 {
867 EnterCriticalSection(&g_filelog_lock);
868 }
869
870 static inline void logfile_unlock(void)
871 {
872 LeaveCriticalSection(&g_filelog_lock);
873 }
874
875 // �R�����g�����O����������
876 static void CommentLogToFile(char *buf, int size)
877 {
878 DWORD wrote;
879
880 if (LogVar == NULL || !LogVar->FileOpen) {
881 char uimsg[MAX_UIMSG];
882 get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
883 get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
884 "It is not opened by the log file yet.", ts.UILanguageFile);
885 ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
886 return;
887 }
888
889 logfile_lock();
890 WriteFile(LogVar->FileHandle, buf, size, &wrote, NULL);
891 WriteFile(LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
892 /* Set Line End Flag
893 2007.05.24 Gentaro
894 */
895 eLineEnd = Line_LineHead;
896 logfile_unlock();
897 }
898
899 // ���O�����[�e�[�g�����B
900 // (2013.3.21 yutaka)
901 static void LogRotate(void)
902 {
903 int loopmax = 10000; // XXX
904 char filename[1024];
905 char newfile[1024], oldfile[1024];
906 int i, k;
907 int dwShareMode = FILE_SHARE_READ;
908 unsigned tid;
909
910 if (! LogVar->FileOpen) return;
911
912 if (LogVar->RotateMode == ROTATE_NONE)
913 return;
914
915 if (LogVar->RotateMode == ROTATE_SIZE) {
916 if (LogVar->ByteCount <= LogVar->RotateSize)
917 return;
918 //OutputDebugPrintf("%s: mode %d size %ld\n", __FUNCTION__, LogVar->RotateMode, LogVar->ByteCount);
919 } else {
920 return;
921 }
922
923 logfile_lock();
924 // ���O�T�C�Y���������������B
925 LogVar->ByteCount = 0;
926
927 // �������������t�@�C�����N���[�Y�����A�������t�@�C�����I�[�v�������B
928 CloseFileSync(LogVar);
929 //_lclose(LogVar->FileHandle);
930
931 // �������[�e�[�V�������X�e�b�v�����w����������
932 if (LogVar->RotateStep > 0)
933 loopmax = LogVar->RotateStep;
934
935 for (i = 1 ; i <= loopmax ; i++) {
936 _snprintf_s(filename, sizeof(filename), _TRUNCATE, "%s.%d", LogVar->FullName, i);
937 if (_access_s(filename, 0) != 0)
938 break;
939 }
940 if (i > loopmax) {
941 // �������������������������A�������t�@�C�������p�������B
942 i = loopmax;
943 }
944
945 // ���t�@�C�������l�[���B
946 for (k = i-1 ; k >= 0 ; k--) {
947 if (k == 0)
948 strncpy_s(oldfile, sizeof(oldfile), LogVar->FullName, _TRUNCATE);
949 else
950 _snprintf_s(oldfile, sizeof(oldfile), _TRUNCATE, "%s.%d", LogVar->FullName, k);
951 _snprintf_s(newfile, sizeof(newfile), _TRUNCATE, "%s.%d", LogVar->FullName, k+1);
952 remove(newfile);
953 if (rename(oldfile, newfile) != 0) {
954 OutputDebugPrintf("%s: rename %d\n", __FUNCTION__, errno);
955 }
956 }
957
958 // ���I�[�v��
959 if (!ts.LogLockExclusive) {
960 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
961 }
962 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
963 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
964
965 // �x�����������p�X���b�h���N�����B
966 // (2013.4.19 yutaka)
967 // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
968 // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
969 // �����������������C�������B
970 // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
971 // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
972 // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
973 // (2016.9.26 yutaka)
974 LogVar->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
975 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
976 LogVar->LogThreadId = tid;
977 if (LogVar->LogThreadEvent != NULL) {
978 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
979 CloseHandle(LogVar->LogThreadEvent);
980 }
981
982 logfile_unlock();
983
984 }
985
986 /**
987 * �o�b�t�@�������O���t�@�C������������
988 */
989 static void LogToFile(void)
990 {
991 PCHAR Buf;
992 int Start, Count;
993 BYTE b;
994 PCHAR WriteBuf;
995 DWORD WriteBufMax, WriteBufLen;
996 CHAR tmp[128];
997 DWORD wrote;
998
999 if (! LogVar->FileOpen) return;
1000 if (FileLog)
1001 {
1002 Buf = cv.LogBuf;
1003 Start = cv.LStart;
1004 Count = cv.LCount;
1005 }
1006 else if (BinLog)
1007 {
1008 Buf = cv.BinBuf;
1009 Start = cv.BStart;
1010 Count = cv.BCount;
1011 }
1012 else
1013 return;
1014
1015 if (Buf==NULL) return;
1016 if (Count==0) return;
1017
1018 // ���b�N������(2004.8.6 yutaka)
1019 logfile_lock();
1020
1021 if (ts.DeferredLogWriteMode) {
1022 WriteBufMax = 8192;
1023 WriteBufLen = 0;
1024 WriteBuf = (PCHAR)malloc(WriteBufMax);
1025 while (Get1(Buf,&Start,&Count,&b)) {
1026 if (!FLogIsPause() && (! cv.ProtoFlag))
1027 {
1028 tmp[0] = 0;
1029 if ( ts.LogTimestamp && eLineEnd ) {
1030 char *strtime = NULL;
1031
1032 switch (ts.LogTimestampType) {
1033 case TIMESTAMP_LOCAL:
1034 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1035 break;
1036 case TIMESTAMP_UTC:
1037 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1038 break;
1039 case TIMESTAMP_ELAPSED_LOGSTART:
1040 strtime = strelapsed(LogVar->StartTime);
1041 break;
1042 case TIMESTAMP_ELAPSED_CONNECTED:
1043 strtime = strelapsed(cv.ConnectedTime);
1044 break;
1045 }
1046
1047 /* 2007.05.24 Gentaro */
1048 if( eLineEnd == Line_FileHead ){
1049 strncat_s(tmp, sizeof(tmp), "\r\n", _TRUNCATE);
1050 }
1051 strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE);
1052 strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE);
1053 strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE);
1054 }
1055
1056 /* 2007.05.24 Gentaro */
1057 if( b == 0x0a ){
1058 eLineEnd = Line_LineHead; /* set endmark*/
1059 }
1060 else {
1061 eLineEnd = Line_Other; /* clear endmark*/
1062 }
1063
1064 if (WriteBufLen >= (WriteBufMax*4/5)) {
1065 WriteBufMax *= 2;
1066 WriteBuf = (PCHAR)realloc(WriteBuf, WriteBufMax);
1067 }
1068 memcpy(&WriteBuf[WriteBufLen], tmp, strlen(tmp));
1069 WriteBufLen += strlen(tmp);
1070 WriteBuf[WriteBufLen++] = b;
1071
1072 (LogVar->ByteCount)++;
1073 }
1074 }
1075
1076 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)WriteBuf, WriteBufLen);
1077
1078 } else {
1079
1080 while (Get1(Buf,&Start,&Count,&b))
1081 {
1082 if (!FLogIsPause() && (! cv.ProtoFlag))
1083 {
1084 if ( ts.LogTimestamp && eLineEnd ) {
1085 char *strtime = NULL;
1086
1087 switch (ts.LogTimestampType) {
1088 case TIMESTAMP_LOCAL:
1089 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1090 break;
1091 case TIMESTAMP_UTC:
1092 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1093 break;
1094 case TIMESTAMP_ELAPSED_LOGSTART:
1095 strtime = strelapsed(LogVar->StartTime);
1096 break;
1097 case TIMESTAMP_ELAPSED_CONNECTED:
1098 strtime = strelapsed(cv.ConnectedTime);
1099 break;
1100 }
1101 WriteFile(LogVar->FileHandle, "[", 1, &wrote, NULL);
1102 WriteFile(LogVar->FileHandle, strtime, strlen(strtime), &wrote, NULL);
1103 WriteFile(LogVar->FileHandle, "] ", 2, &wrote, NULL);
1104 }
1105
1106 /* 2007.05.24 Gentaro */
1107 if( b == 0x0a ){
1108 eLineEnd = Line_LineHead; /* set endmark*/
1109 }
1110 else {
1111 eLineEnd = Line_Other; /* clear endmark*/
1112 }
1113
1114 WriteFile(LogVar->FileHandle, (PCHAR)&b, 1, &wrote, NULL);
1115 (LogVar->ByteCount)++;
1116 }
1117 }
1118
1119 }
1120
1121 logfile_unlock();
1122
1123 if (FileLog)
1124 {
1125 cv.LStart = Start;
1126 cv.LCount = Count;
1127 }
1128 else {
1129 cv.BStart = Start;
1130 cv.BCount = Count;
1131 }
1132 if (FLogIsPause() || cv.ProtoFlag) return;
1133 if (FLogDlg!=NULL)
1134 //FLogDlg->RefreshNum(LogVar);
1135 FLogDlg->RefreshNum(LogVar->StartTime, LogVar->FileSize, LogVar->ByteCount);
1136
1137
1138 // ���O�E���[�e�[�g
1139 LogRotate();
1140
1141 }
1142
1143 static BOOL CreateLogBuf(void)
1144 {
1145 if (cv.HLogBuf==NULL)
1146 {
1147 cv.HLogBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1148 cv.LogBuf = NULL;
1149 cv.LogPtr = 0;
1150 cv.LStart = 0;
1151 cv.LCount = 0;
1152 }
1153 return (cv.HLogBuf!=NULL);
1154 }
1155
1156 static void FreeLogBuf(void)
1157 {
1158 if ((cv.HLogBuf==NULL) || FileLog)
1159 return;
1160 if (cv.LogBuf!=NULL)
1161 GlobalUnlock(cv.HLogBuf);
1162 GlobalFree(cv.HLogBuf);
1163 cv.HLogBuf = NULL;
1164 cv.LogBuf = NULL;
1165 cv.LogPtr = 0;
1166 cv.LStart = 0;
1167 cv.LCount = 0;
1168 }
1169
1170 static BOOL CreateBinBuf(void)
1171 {
1172 if (cv.HBinBuf==NULL)
1173 {
1174 cv.HBinBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1175 cv.BinBuf = NULL;
1176 cv.BinPtr = 0;
1177 cv.BStart = 0;
1178 cv.BCount = 0;
1179 }
1180 return (cv.HBinBuf!=NULL);
1181 }
1182
1183 static void FreeBinBuf(void)
1184 {
1185 if ((cv.HBinBuf==NULL) || BinLog)
1186 return;
1187 if (cv.BinBuf!=NULL)
1188 GlobalUnlock(cv.HBinBuf);
1189 GlobalFree(cv.HBinBuf);
1190 cv.HBinBuf = NULL;
1191 cv.BinBuf = NULL;
1192 cv.BinPtr = 0;
1193 cv.BStart = 0;
1194 cv.BCount = 0;
1195 }
1196
1197 static void FileTransEnd_(void)
1198 {
1199 FileLog = FALSE;
1200 BinLog = FALSE;
1201 cv.Log1Byte = NULL;
1202 cv.Log1Bin = NULL;
1203 cv.LogBinSkip = NULL;
1204 if (FLogDlg!=NULL)
1205 {
1206 FLogDlg->DestroyWindow();
1207 FLogDlg = NULL;
1208 }
1209 if (LogVar != NULL)
1210 {
1211 CloseFileSync(LogVar);
1212 free(LogVar);
1213 LogVar = NULL;
1214 }
1215 FreeLogBuf();
1216 FreeBinBuf();
1217 FreeTTFILE();
1218 }
1219
1220
1221 /**
1222 * ���O���|�[�Y����
1223 * ���� FLogChangeButton() ������
1224 */
1225 void FLogPause(BOOL Pause)
1226 {
1227 if (FLogDlg!=NULL)
1228 FLogDlg->ChangeButton(Pause);
1229 FileTransPause(OpLog, Pause);
1230 }
1231
1232 /**
1233 * ���O���[�e�[�g������
1234 * ���O���T�C�Y��<size>�o�C�g���������������A���[�e�[�V��������������������
1235 */
1236 void FLogRotateSize(size_t size)
1237 {
1238 if (LogVar == NULL) {
1239 return;
1240 }
1241 LogVar->RotateMode = ROTATE_SIZE;
1242 LogVar->RotateSize = size;
1243 }
1244
1245 /**
1246 * ���O���[�e�[�g������
1247 * ���O�t�@�C������������������
1248 */
1249 void FLogRotateRotate(int step)
1250 {
1251 if (LogVar == NULL) {
1252 return;
1253 }
1254 LogVar->RotateStep = step;
1255 }
1256
1257 /**
1258 * ���O���[�e�[�g������
1259 * ���[�e�[�V���������~
1260 */
1261 void FLogRotateHalt(void)
1262 {
1263 if (LogVar == NULL) {
1264 return;
1265 }
1266 LogVar->RotateMode = ROTATE_NONE;
1267 LogVar->RotateSize = 0;
1268 LogVar->RotateStep = 0;
1269 }
1270
1271 static INT_PTR CALLBACK OnCommentDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp)
1272 {
1273 static const DlgTextInfo TextInfos[] = {
1274 { 0, "DLG_COMMENT_TITLE" },
1275 { IDOK, "BTN_OK" }
1276 };
1277 char buf[256];
1278 UINT ret;
1279
1280 switch (msg) {
1281 case WM_INITDIALOG:
1282 //SetDlgItemText(hDlgWnd, IDC_EDIT_COMMENT, "�T���v��");
1283 // �G�f�B�b�g�R���g���[�����t�H�[�J�X��������
1284 SetFocus(GetDlgItem(hDlgWnd, IDC_EDIT_COMMENT));
1285 SetDlgTexts(hDlgWnd, TextInfos, _countof(TextInfos), ts.UILanguageFile);
1286 return FALSE;
1287
1288 case WM_COMMAND:
1289 switch (LOWORD(wp)) {
1290 case IDOK:
1291 memset(buf, 0, sizeof(buf));
1292 ret = GetDlgItemTextA(hDlgWnd, IDC_EDIT_COMMENT, buf, sizeof(buf) - 1);
1293 if (ret > 0) { // �e�L�X�g��������
1294 //buf[sizeof(buf) - 1] = '\0'; // null-terminate
1295 CommentLogToFile(buf, ret);
1296 }
1297 TTEndDialog(hDlgWnd, IDOK);
1298 break;
1299 default:
1300 return FALSE;
1301 }
1302 break;
1303 case WM_CLOSE:
1304 TTEndDialog(hDlgWnd, 0);
1305 return TRUE;
1306
1307 default:
1308 return FALSE;
1309 }
1310 return TRUE;
1311 }
1312
1313 void FLogAddCommentDlg(HINSTANCE hInst, HWND hWnd)
1314 {
1315 // ���O�t�@�C�����R�����g���������� (2004.8.6 yutaka)
1316 TTDialogBox(hInst, MAKEINTRESOURCE(IDD_COMMENT_DIALOG),
1317 HVTWin, OnCommentDlgProc);
1318 }
1319
1320 void FLogClose(void)
1321 {
1322 if (LogVar == NULL) {
1323 return;
1324 }
1325
1326 FileTransEnd_();
1327 }
1328
1329 /**
1330 * ���O���I�[�v������
1331 * @param[in] fname ���O�t�@�C����, CreateFile()���n������
1332 *
1333 * ���O�t�@�C������strftime���W�J�������s���������B
1334 * FLogGetLogFilename() �� FLogOpenDialog() ��
1335 * �t�@�C�����������������B
1336 */
1337 BOOL FLogOpen(const char *fname)
1338 {
1339 BOOL ret;
1340
1341 if (LogVar != NULL) {
1342 return FALSE;
1343 }
1344 if ((FileLog) || (BinLog)) return FALSE;
1345
1346 //
1347 PFileVar fv = (PFileVar)malloc(sizeof(TFileVar));
1348 if (fv == NULL) {
1349 return FALSE;
1350 }
1351 LogVar = fv;
1352 memset(fv, 0, sizeof(TFileVar));
1353
1354 fv->FileOpen = FALSE;
1355 fv->OverWrite = ((ts.FTFlag & FT_RENAME) == 0);
1356 fv->Success = FALSE;
1357 fv->NoMsg = FALSE;
1358 fv->HideDialog = FALSE;
1359
1360 LogVar->DirLen = 0;
1361 LogVar->NoMsg = TRUE;
1362
1363 ret = LogStart(fname);
1364 return ret;
1365 }
1366
1367 BOOL FLogIsOpend(void)
1368 {
1369 // LogVar->FileOpen
1370 return LogVar != NULL;
1371 }
1372
1373 void FLogWriteStr(const char *str)
1374 {
1375 if (LogVar != NULL)
1376 {
1377 DWORD wrote;
1378 size_t len = strlen(str);
1379 WriteFile(LogVar->FileHandle, str, len, &wrote, NULL);
1380 LogVar->ByteCount =
1381 LogVar->ByteCount + len;
1382 if (FLogDlg!=NULL)
1383 //FLogDlg->RefreshNum(LogVar);
1384 FLogDlg->RefreshNum(LogVar->StartTime, LogVar->FileSize, LogVar->ByteCount);
1385 }
1386 }
1387
1388 void FLogInfo(char *param_ptr, size_t param_len)
1389 {
1390 if (LogVar) {
1391 param_ptr[0] = '0'
1392 + (ts.LogBinary != 0)
1393 + ((ts.Append != 0) << 1)
1394 + ((ts.LogTypePlainText != 0) << 2)
1395 + ((ts.LogTimestamp != 0) << 3)
1396 + ((ts.LogHideDialog != 0) << 4);
1397 strncpy_s(param_ptr + 1, param_len - 1, LogVar->FullName, _TRUNCATE);
1398 }
1399 else {
1400 param_ptr[0] = '0' - 1;
1401 param_ptr[1] = 0;
1402 }
1403 }
1404
1405 /**
1406 * ���������O�t�@�C����������
1407 */
1408 const char *FLogGetFilename()
1409 {
1410 if (LogVar == NULL) {
1411 return NULL;
1412 }
1413 return LogVar->FullName;
1414 }
1415
1416 /**
1417 * ���O�_�C�A���O���J��
1418 * @param[in,out] info.filename �t�@�C���������l
1419 * OK���A�t�@�C�����A�s�v����������free()��������
1420 * @retval TRUE [ok] ����������
1421 * @retval FALSE �L�����Z��������
1422 */
1423 BOOL FLogOpenDialog(HINSTANCE hInst, HWND hWnd, FLogDlgInfo_t *info)
1424 {
1425 LogDlgWork_t *work = (LogDlgWork_t *)calloc(sizeof(LogDlgWork_t), 1);
1426 char *filenameA = ToCharW(info->filename);
1427 char *srcfnameA = FLogGetLogFilename(filenameA);
1428 wchar_t *srcfnameW = ToWcharA(srcfnameA);
1429 free(filenameA);
1430 free(srcfnameA);
1431 work->info = info;
1432 work->info->filename = srcfnameW;
1433 work->pts = &ts;
1434 INT_PTR ret = TTDialogBoxParam(
1435 hInst, MAKEINTRESOURCE(IDD_LOGDLG),
1436 hWnd, LogFnHook, (LPARAM)work);
1437 free(srcfnameW);
1438 free(work);
1439 return ret == IDOK ? TRUE : FALSE;
1440 }
1441
1442 /**
1443 * ���O�t�@�C����������
1444 * ���O�t�@�C�����p���C�����s��
1445 * - strftime() ���������t�W�J
1446 * - �������������O�t�@�C���t�H���_������
1447 * - �z�X�g��,�|�[�g�����W�J
1448 *
1449 * @param[in] log_filename �t�@�C����(����/��������������ok)
1450 * NULL�������f�t�H���g�t�@�C����������
1451 * strftime�`��ok
1452 * @return �t���p�X�t�@�C����
1453 * �s�v���������� free() ��������
1454 */
1455 char *FLogGetLogFilename(const char *log_filename)
1456 {
1457 // �t�H���_
1458 char FileDirExpanded[MAX_PATH];
1459 char *logdir;
1460 if (strlen(ts.LogDefaultPath) > 0) {
1461 logdir = ts.LogDefaultPath;
1462 }
1463 else if (strlen(ts.FileDir) > 0) {
1464 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1465 logdir = FileDirExpanded;
1466 }
1467 else {
1468 logdir = ts.HomeDir;
1469 }
1470
1471 // ���������t�@�C����
1472 char base_name[MAX_PATH];
1473 if (log_filename == NULL) {
1474 strncpy_s(base_name, _countof(base_name), ts.LogDefaultName, _TRUNCATE);
1475 }
1476 else {
1477 strncpy_s(base_name, _countof(base_name), log_filename, _TRUNCATE);
1478 }
1479
1480 // �t���p�X��
1481 char full_path[MAX_PATH];
1482 ConvFName(logdir, base_name, sizeof(base_name), "", full_path, sizeof(full_path));
1483 ParseStrftimeFileName(full_path, sizeof(full_path));
1484 ConvertLogname(full_path, sizeof(full_path));
1485
1486 return _strdup(full_path);
1487 }
1488
1489 BOOL FLogIsPause()
1490 {
1491 return ((cv.FilePause & OpLog) !=0);
1492 }
1493
1494 void FLogWindow(int nCmdShow)
1495 {
1496 if (FLogDlg == NULL)
1497 return;
1498
1499 HWND HWndLog = FLogDlg->m_hWnd;
1500 ShowWindow(HWndLog, nCmdShow);
1501 if (nCmdShow == SW_RESTORE) {
1502 // �g���X�^�C�� WS_EX_NOACTIVATE ��������������
1503 SetForegroundWindow(HWndLog);
1504 }
1505 }
1506
1507 void FLogShowDlg(void)
1508 {
1509 if (FLogDlg != NULL) {
1510 FLogDlg->ShowWindow(SW_SHOWNORMAL);
1511 SetForegroundWindow(FLogDlg->GetSafeHwnd());
1512 }
1513 }
1514
1515 /**
1516 * ���O��1byte��������
1517 * LogPut1() ������?
1518 */
1519 //void Log1Bin(PComVar cv, BYTE b)
1520 static void Log1Bin(BYTE b)
1521 {
1522 if (((cv.FilePause & OpLog)!=0) || cv.ProtoFlag) {
1523 return;
1524 }
1525 if (cv.BinSkip > 0) {
1526 cv.BinSkip--;
1527 return;
1528 }
1529 cv.BinBuf[cv.BinPtr] = b;
1530 cv.BinPtr++;
1531 if (cv.BinPtr>=InBuffSize) {
1532 cv.BinPtr = cv.BinPtr-InBuffSize;
1533 }
1534 if (cv.BCount>=InBuffSize) {
1535 cv.BCount = InBuffSize;
1536 cv.BStart = cv.BinPtr;
1537 }
1538 else {
1539 cv.BCount++;
1540 }
1541 }
1542
1543 static void LogBinSkip(int add)
1544 {
1545 if (cv.HBinBuf!=0 ) {
1546 cv.BinSkip += add;
1547 }
1548 }
1549
1550 /**
1551 * ���O�o�b�t�@���������������f�[�^���o�C�g��������
1552 */
1553 int FLogGetCount(void)
1554 {
1555 if (FileLog) {
1556 return cv.LCount;
1557 }
1558 if (BinLog) {
1559 return cv.BCount;
1560 }
1561 return 0;
1562 }
1563
1564 /**
1565 * �o�b�t�@�������O���t�@�C������������
1566 */
1567 void FLogWriteFile(void)
1568 {
1569 if (cv.LogBuf!=NULL)
1570 {
1571 if (FileLog) {
1572 LogToFile();
1573 }
1574 GlobalUnlock(cv.HLogBuf);
1575 cv.LogBuf = NULL;
1576 }
1577
1578 if (cv.BinBuf!=NULL)
1579 {
1580 if (BinLog) {
1581 LogToFile();
1582 }
1583 GlobalUnlock(cv.HBinBuf);
1584 cv.BinBuf = NULL;
1585 }
1586 }

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