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

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