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 8902 - (show annotations) (download) (as text)
Tue Aug 18 15:30:18 2020 UTC (3 years, 7 months ago) by zmatsuo
File MIME type: text/x-c++src
File size: 38822 byte(s)
ftdlgのファイル名表示が誤っていたので修正

- フルパスからファイル名を抽出するコードを ftdlg.cpp に移動した
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 fv->FileName = NULL;
684 FixLogOption();
685
686 if (ts.LogBinary > 0)
687 {
688 BinLog = TRUE;
689 FileLog = FALSE;
690 if (! CreateBinBuf())
691 {
692 return FALSE;
693 }
694 }
695 else {
696 BinLog = FALSE;
697 FileLog = TRUE;
698 if (! CreateLogBuf())
699 {
700 return FALSE;
701 }
702 }
703 cv.LStart = cv.LogPtr;
704 cv.LCount = 0;
705
706 OpenLogFile(fv);
707 if (LogVar->FileHandle == INVALID_HANDLE_VALUE) {
708 return FALSE;
709 }
710
711 /* 2007.05.24 Gentaro */
712 fv->eLineEnd = Line_LineHead;
713 if (ts.Append > 0)
714 {
715 SetFilePointer(LogVar->FileHandle, 0, NULL, FILE_END);
716 /* 2007.05.24 Gentaro
717 If log file already exists,
718 a newline is inserted before the first timestamp.
719 */
720 fv->eLineEnd = Line_FileHead;
721 }
722
723 // Log rotate configuration
724 LogVar->RotateMode = ts.LogRotate;
725 LogVar->RotateSize = ts.LogRotateSize;
726 LogVar->RotateStep = ts.LogRotateStep;
727
728 // Log rotate���L���������A�����t�@�C���T�C�Y�����������B
729 // �������t�@�C�������������T�C�Y�����[�e�[�g�������������C���B
730 // (2016.4.9 yutaka)
731 if (LogVar->RotateMode != ROTATE_NONE) {
732 DWORD size = GetFileSize(LogVar->FileHandle, NULL);
733 if (size == -1) {
734 return FALSE;
735 }
736 LogVar->ByteCount = size;
737 }
738 else {
739 LogVar->ByteCount = 0;
740 }
741
742 if (! OpenFTDlg_(LogVar)) {
743 return FALSE;
744 }
745
746 LogVar->IsPause = FALSE;
747 LogVar->StartTime = GetTickCount();
748
749 if (ts.DeferredLogWriteMode) {
750 StartThread(LogVar);
751 }
752
753 // �����o�b�t�@�������f�[�^�������������o���������A
754 // ���O�������J�n�����B
755 // (2013.9.29 yutaka)
756 if (ts.LogAllBuffIncludedInFirst) {
757 DWORD ofs, size, written_size;
758 char buf[512];
759 const char *crlf = "\r\n";
760 DWORD crlf_len = 2;
761 for (ofs = 0 ; ; ofs++ ) {
762 // 1�����s�����������B���������������A�G�X�P�[�v�V�[�P���X�������������B
763 size = BuffGetAnyLineData(ofs, buf, sizeof(buf));
764 if (size == -1)
765 break;
766
767 #if 0
768 if (ts.DeferredLogWriteMode) { // �x����������
769 char *pbuf = (char *)malloc(size + 2);
770 memcpy(pbuf, buf, size);
771 pbuf[size] = '\r';
772 pbuf[size+1] = '\n';
773 Sleep(1); // �X���b�h�L���[�����������������A�R���e�L�X�g�X�C�b�`�������B
774 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)pbuf, size + 2);
775 } else { // �������B�l�b�g���[�N�o�R�����x���B
776 #endif
777 WriteFile(LogVar->FileHandle, buf, size, &written_size, NULL);
778 WriteFile(LogVar->FileHandle, crlf, crlf_len, &written_size, NULL);
779 #if 0
780 }
781 #endif
782 }
783 }
784
785 if (FileLog) {
786 cv.Log1Byte = LogPut1;
787 }
788 if (BinLog) {
789 cv.Log1Bin = Log1Bin;
790 cv.LogBinSkip = LogBinSkip;
791 }
792
793 return TRUE;
794 }
795
796 /**
797 * ���O��1byte��������
798 * �o�b�t�@��������������
799 * ���������������� LogToFile() ���s������
800 */
801 void LogPut1(BYTE b)
802 {
803 cv.LogBuf[cv.LogPtr] = b;
804 cv.LogPtr++;
805 if (cv.LogPtr>=InBuffSize)
806 cv.LogPtr = cv.LogPtr-InBuffSize;
807
808 if (FileLog)
809 {
810 if (cv.LCount>=InBuffSize)
811 {
812 cv.LCount = InBuffSize;
813 cv.LStart = cv.LogPtr;
814 }
815 else
816 cv.LCount++;
817 }
818 else
819 cv.LCount = 0;
820 }
821
822 static BOOL Get1(PCHAR Buf, int *Start, int *Count, PBYTE b)
823 {
824 if (*Count<=0) return FALSE;
825 *b = Buf[*Start];
826 (*Start)++;
827 if (*Start>=InBuffSize)
828 *Start = *Start-InBuffSize;
829 (*Count)--;
830 return TRUE;
831 }
832
833
834
835 static CRITICAL_SECTION g_filelog_lock; /* ���b�N�p���� */
836
837 void logfile_lock_initialize(void)
838 {
839 InitializeCriticalSection(&g_filelog_lock);
840 }
841
842 static inline void logfile_lock(void)
843 {
844 EnterCriticalSection(&g_filelog_lock);
845 }
846
847 static inline void logfile_unlock(void)
848 {
849 LeaveCriticalSection(&g_filelog_lock);
850 }
851
852 // �R�����g�����O����������
853 static void CommentLogToFile(char *buf, int size)
854 {
855 DWORD wrote;
856
857 if (LogVar == NULL) {
858 char uimsg[MAX_UIMSG];
859 get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
860 get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
861 "It is not opened by the log file yet.", ts.UILanguageFile);
862 ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
863 return;
864 }
865
866 logfile_lock();
867 WriteFile(LogVar->FileHandle, buf, size, &wrote, NULL);
868 WriteFile(LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
869 /* Set Line End Flag
870 2007.05.24 Gentaro
871 */
872 LogVar->eLineEnd = Line_LineHead;
873 logfile_unlock();
874 }
875
876 // ���O�����[�e�[�g�����B
877 // (2013.3.21 yutaka)
878 static void LogRotate(void)
879 {
880 int loopmax = 10000; // XXX
881 int i, k;
882
883 if (LogVar->RotateMode == ROTATE_NONE)
884 return;
885
886 if (LogVar->RotateMode == ROTATE_SIZE) {
887 if (LogVar->ByteCount <= LogVar->RotateSize)
888 return;
889 //OutputDebugPrintf("%s: mode %d size %ld\n", __FUNCTION__, LogVar->RotateMode, LogVar->ByteCount);
890 } else {
891 return;
892 }
893
894 logfile_lock();
895 // ���O�T�C�Y���������������B
896 LogVar->ByteCount = 0;
897
898 // �������������t�@�C�����N���[�Y�����A�������t�@�C�����I�[�v�������B
899 CloseFileSync(LogVar);
900
901 // �������[�e�[�V�������X�e�b�v�����w����������
902 if (LogVar->RotateStep > 0)
903 loopmax = LogVar->RotateStep;
904
905 for (i = 1 ; i <= loopmax ; i++) {
906 wchar_t *filename;
907 aswprintf(&filename, L"%s.%d", LogVar->FullName, i);
908 DWORD attr = _GetFileAttributesW(filename);
909 free(filename);
910 if (attr == INVALID_FILE_ATTRIBUTES)
911 break;
912 }
913 if (i > loopmax) {
914 // �������������������������A�������t�@�C�������p�������B
915 i = loopmax;
916 }
917
918 // ���t�@�C�������l�[���B
919 for (k = i-1 ; k >= 0 ; k--) {
920 wchar_t *oldfile;
921 if (k == 0)
922 oldfile = _wcsdup(LogVar->FullName);
923 else
924 aswprintf(&oldfile, L"%s.%d", LogVar->FullName, k);
925 wchar_t *newfile;
926 aswprintf(&newfile, L"%s.%d", LogVar->FullName, k+1);
927 _DeleteFileW(newfile);
928 if (_MoveFileW(oldfile, newfile) == 0) {
929 OutputDebugPrintf("%s: rename %d\n", __FUNCTION__, errno);
930 }
931 free(oldfile);
932 free(newfile);
933 }
934
935 // ���I�[�v��
936 OpenLogFile(LogVar);
937 if (ts.DeferredLogWriteMode) {
938 StartThread(LogVar);
939 }
940
941 logfile_unlock();
942 }
943
944 /**
945 * �o�b�t�@�������O���t�@�C������������
946 */
947 static void LogToFile(void)
948 {
949 PCHAR Buf;
950 int Start, Count;
951 BYTE b;
952 PCHAR WriteBuf;
953 DWORD WriteBufMax, WriteBufLen;
954 CHAR tmp[128];
955 DWORD wrote;
956 PFileVar fv = LogVar;
957
958 if (FileLog)
959 {
960 Buf = cv.LogBuf;
961 Start = cv.LStart;
962 Count = cv.LCount;
963 }
964 else if (BinLog)
965 {
966 Buf = cv.BinBuf;
967 Start = cv.BStart;
968 Count = cv.BCount;
969 }
970 else
971 return;
972
973 if (Buf==NULL) return;
974 if (Count==0) return;
975
976 // ���b�N������(2004.8.6 yutaka)
977 logfile_lock();
978
979 if (ts.DeferredLogWriteMode) {
980 WriteBufMax = 8192;
981 WriteBufLen = 0;
982 WriteBuf = (PCHAR)malloc(WriteBufMax);
983 while (Get1(Buf,&Start,&Count,&b)) {
984 if (!FLogIsPause() && (! cv.ProtoFlag))
985 {
986 tmp[0] = 0;
987 if ( ts.LogTimestamp && fv->eLineEnd ) {
988 char *strtime = NULL;
989
990 switch (ts.LogTimestampType) {
991 case TIMESTAMP_LOCAL:
992 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
993 break;
994 case TIMESTAMP_UTC:
995 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
996 break;
997 case TIMESTAMP_ELAPSED_LOGSTART:
998 strtime = strelapsed(LogVar->StartTime);
999 break;
1000 case TIMESTAMP_ELAPSED_CONNECTED:
1001 strtime = strelapsed(cv.ConnectedTime);
1002 break;
1003 }
1004
1005 /* 2007.05.24 Gentaro */
1006 if(fv->eLineEnd == Line_FileHead ){
1007 strncat_s(tmp, sizeof(tmp), "\r\n", _TRUNCATE);
1008 }
1009 strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE);
1010 strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE);
1011 strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE);
1012 }
1013
1014 /* 2007.05.24 Gentaro */
1015 if( b == 0x0a ){
1016 fv->eLineEnd = Line_LineHead; /* set endmark*/
1017 }
1018 else {
1019 fv->eLineEnd = Line_Other; /* clear endmark*/
1020 }
1021
1022 if (WriteBufLen >= (WriteBufMax*4/5)) {
1023 WriteBufMax *= 2;
1024 WriteBuf = (PCHAR)realloc(WriteBuf, WriteBufMax);
1025 }
1026 memcpy(&WriteBuf[WriteBufLen], tmp, strlen(tmp));
1027 WriteBufLen += strlen(tmp);
1028 WriteBuf[WriteBufLen++] = b;
1029
1030 (LogVar->ByteCount)++;
1031 }
1032 }
1033
1034 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)WriteBuf, WriteBufLen);
1035
1036 } else {
1037
1038 while (Get1(Buf,&Start,&Count,&b))
1039 {
1040 if (!FLogIsPause() && (! cv.ProtoFlag))
1041 {
1042 if ( ts.LogTimestamp && fv->eLineEnd ) {
1043 char *strtime = NULL;
1044
1045 switch (ts.LogTimestampType) {
1046 case TIMESTAMP_LOCAL:
1047 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1048 break;
1049 case TIMESTAMP_UTC:
1050 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1051 break;
1052 case TIMESTAMP_ELAPSED_LOGSTART:
1053 strtime = strelapsed(LogVar->StartTime);
1054 break;
1055 case TIMESTAMP_ELAPSED_CONNECTED:
1056 strtime = strelapsed(cv.ConnectedTime);
1057 break;
1058 }
1059 WriteFile(LogVar->FileHandle, "[", 1, &wrote, NULL);
1060 WriteFile(LogVar->FileHandle, strtime, strlen(strtime), &wrote, NULL);
1061 WriteFile(LogVar->FileHandle, "] ", 2, &wrote, NULL);
1062 }
1063
1064 /* 2007.05.24 Gentaro */
1065 if( b == 0x0a ){
1066 fv->eLineEnd = Line_LineHead; /* set endmark*/
1067 }
1068 else {
1069 fv->eLineEnd = Line_Other; /* clear endmark*/
1070 }
1071
1072 WriteFile(LogVar->FileHandle, (PCHAR)&b, 1, &wrote, NULL);
1073 (LogVar->ByteCount)++;
1074 }
1075 }
1076
1077 }
1078
1079 logfile_unlock();
1080
1081 if (FileLog)
1082 {
1083 cv.LStart = Start;
1084 cv.LCount = Count;
1085 }
1086 else {
1087 cv.BStart = Start;
1088 cv.BCount = Count;
1089 }
1090 if (FLogIsPause() || cv.ProtoFlag) return;
1091 LogVar->FLogDlg->RefreshNum(LogVar->StartTime, LogVar->FileSize, LogVar->ByteCount);
1092
1093
1094 // ���O�E���[�e�[�g
1095 LogRotate();
1096 }
1097
1098 static BOOL CreateLogBuf(void)
1099 {
1100 if (cv.HLogBuf==NULL)
1101 {
1102 cv.HLogBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1103 cv.LogBuf = NULL;
1104 cv.LogPtr = 0;
1105 cv.LStart = 0;
1106 cv.LCount = 0;
1107 }
1108 return (cv.HLogBuf!=NULL);
1109 }
1110
1111 static void FreeLogBuf(void)
1112 {
1113 if ((cv.HLogBuf==NULL) || FileLog)
1114 return;
1115 if (cv.LogBuf!=NULL)
1116 GlobalUnlock(cv.HLogBuf);
1117 GlobalFree(cv.HLogBuf);
1118 cv.HLogBuf = NULL;
1119 cv.LogBuf = NULL;
1120 cv.LogPtr = 0;
1121 cv.LStart = 0;
1122 cv.LCount = 0;
1123 }
1124
1125 static BOOL CreateBinBuf(void)
1126 {
1127 if (cv.HBinBuf==NULL)
1128 {
1129 cv.HBinBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1130 cv.BinBuf = NULL;
1131 cv.BinPtr = 0;
1132 cv.BStart = 0;
1133 cv.BCount = 0;
1134 }
1135 return (cv.HBinBuf!=NULL);
1136 }
1137
1138 static void FreeBinBuf(void)
1139 {
1140 if ((cv.HBinBuf==NULL) || BinLog)
1141 return;
1142 if (cv.BinBuf!=NULL)
1143 GlobalUnlock(cv.HBinBuf);
1144 GlobalFree(cv.HBinBuf);
1145 cv.HBinBuf = NULL;
1146 cv.BinBuf = NULL;
1147 cv.BinPtr = 0;
1148 cv.BStart = 0;
1149 cv.BCount = 0;
1150 }
1151
1152 static void FileTransEnd_(void)
1153 {
1154 if (LogVar == NULL) {
1155 return;
1156 }
1157 FileLog = FALSE;
1158 BinLog = FALSE;
1159 cv.Log1Byte = NULL;
1160 cv.Log1Bin = NULL;
1161 cv.LogBinSkip = NULL;
1162 PFileTransDlg FLogDlg = LogVar->FLogDlg;
1163 if (FLogDlg != NULL) {
1164 FLogDlg->DestroyWindow();
1165 FLogDlg = NULL;
1166 }
1167 CloseFileSync(LogVar);
1168 FreeLogBuf();
1169 FreeBinBuf();
1170 free(LogVar);
1171 LogVar = NULL;
1172 }
1173
1174 /**
1175 * ���O���|�[�Y����
1176 */
1177 void FLogPause(BOOL Pause)
1178 {
1179 if (LogVar == NULL) {
1180 return;
1181 }
1182 LogVar->IsPause = Pause;
1183 LogVar->FLogDlg->ChangeButton(Pause);
1184 }
1185
1186 /**
1187 * ���O���[�e�[�g������
1188 * ���O���T�C�Y��<size>�o�C�g���������������A���[�e�[�V��������������������
1189 */
1190 void FLogRotateSize(size_t size)
1191 {
1192 if (LogVar == NULL) {
1193 return;
1194 }
1195 LogVar->RotateMode = ROTATE_SIZE;
1196 LogVar->RotateSize = size;
1197 }
1198
1199 /**
1200 * ���O���[�e�[�g������
1201 * ���O�t�@�C������������������
1202 */
1203 void FLogRotateRotate(int step)
1204 {
1205 if (LogVar == NULL) {
1206 return;
1207 }
1208 LogVar->RotateStep = step;
1209 }
1210
1211 /**
1212 * ���O���[�e�[�g������
1213 * ���[�e�[�V���������~
1214 */
1215 void FLogRotateHalt(void)
1216 {
1217 if (LogVar == NULL) {
1218 return;
1219 }
1220 LogVar->RotateMode = ROTATE_NONE;
1221 LogVar->RotateSize = 0;
1222 LogVar->RotateStep = 0;
1223 }
1224
1225 static INT_PTR CALLBACK OnCommentDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp)
1226 {
1227 static const DlgTextInfo TextInfos[] = {
1228 { 0, "DLG_COMMENT_TITLE" },
1229 { IDOK, "BTN_OK" }
1230 };
1231 UINT ret;
1232
1233 switch (msg) {
1234 case WM_INITDIALOG:
1235 //SetDlgItemText(hDlgWnd, IDC_EDIT_COMMENT, "�T���v��");
1236 // �G�f�B�b�g�R���g���[�����t�H�[�J�X��������
1237 SetFocus(GetDlgItem(hDlgWnd, IDC_EDIT_COMMENT));
1238 SetDlgTexts(hDlgWnd, TextInfos, _countof(TextInfos), ts.UILanguageFile);
1239 return FALSE;
1240
1241 case WM_COMMAND:
1242 switch (LOWORD(wp)) {
1243 case IDOK: {
1244 char buf[256];
1245 memset(buf, 0, sizeof(buf));
1246 ret = GetDlgItemTextA(hDlgWnd, IDC_EDIT_COMMENT, buf, sizeof(buf) - 1);
1247 if (ret > 0) { // �e�L�X�g��������
1248 //buf[sizeof(buf) - 1] = '\0'; // null-terminate
1249 CommentLogToFile(buf, ret);
1250 }
1251 TTEndDialog(hDlgWnd, IDOK);
1252 break;
1253 }
1254 default:
1255 return FALSE;
1256 }
1257 break;
1258 case WM_CLOSE:
1259 TTEndDialog(hDlgWnd, 0);
1260 return TRUE;
1261
1262 default:
1263 return FALSE;
1264 }
1265 return TRUE;
1266 }
1267
1268 void FLogAddCommentDlg(HINSTANCE hInst, HWND hWnd)
1269 {
1270 // ���O�t�@�C�����R�����g���������� (2004.8.6 yutaka)
1271 TTDialogBox(hInst, MAKEINTRESOURCE(IDD_COMMENT_DIALOG),
1272 HVTWin, OnCommentDlgProc);
1273 }
1274
1275 void FLogClose(void)
1276 {
1277 if (LogVar == NULL) {
1278 return;
1279 }
1280
1281 FileTransEnd_();
1282 }
1283
1284 /**
1285 * ���O���I�[�v������
1286 * @param[in] fname ���O�t�@�C����, CreateFile()���n������
1287 *
1288 * ���O�t�@�C������strftime���W�J�������s���������B
1289 * FLogGetLogFilename() �� FLogOpenDialog() ��
1290 * �t�@�C�����������������B
1291 */
1292 BOOL FLogOpen(const wchar_t *fname)
1293 {
1294 BOOL ret;
1295
1296 if (LogVar != NULL) {
1297 return FALSE;
1298 }
1299 if ((FileLog) || (BinLog)) return FALSE;
1300
1301 //
1302 PFileVar fv = (PFileVar)malloc(sizeof(TFileVar));
1303 if (fv == NULL) {
1304 return FALSE;
1305 }
1306 LogVar = fv;
1307 memset(fv, 0, sizeof(TFileVar));
1308 fv->FileHandle = INVALID_HANDLE_VALUE;
1309 fv->LogThread = INVALID_HANDLE_VALUE;
1310 fv->eLineEnd = Line_LineHead;
1311
1312 ret = LogStart(fname);
1313 if (ret == FALSE) {
1314 FileTransEnd_();
1315 }
1316
1317 return ret;
1318 }
1319
1320 BOOL FLogIsOpend(void)
1321 {
1322 return LogVar != NULL;
1323 }
1324
1325 void FLogWriteStr(const char *str)
1326 {
1327 if (LogVar != NULL)
1328 {
1329 DWORD wrote;
1330 size_t len = strlen(str);
1331 WriteFile(LogVar->FileHandle, str, len, &wrote, NULL);
1332 LogVar->ByteCount =
1333 LogVar->ByteCount + len;
1334 LogVar->FLogDlg->RefreshNum(LogVar->StartTime, LogVar->FileSize, LogVar->ByteCount);
1335 }
1336 }
1337
1338 void FLogInfo(char *param_ptr, size_t param_len)
1339 {
1340 if (LogVar) {
1341 param_ptr[0] = '0'
1342 + (ts.LogBinary != 0)
1343 + ((ts.Append != 0) << 1)
1344 + ((ts.LogTypePlainText != 0) << 2)
1345 + ((ts.LogTimestamp != 0) << 3)
1346 + ((ts.LogHideDialog != 0) << 4);
1347 char *filenameU8 = ToU8W(LogVar->FullName);
1348 strncpy_s(param_ptr + 1, param_len - 1, filenameU8, _TRUNCATE);
1349 free(filenameU8);
1350 }
1351 else {
1352 param_ptr[0] = '0' - 1;
1353 param_ptr[1] = 0;
1354 }
1355 }
1356
1357 /**
1358 * ���������O�t�@�C����������
1359 */
1360 const wchar_t *FLogGetFilename(void)
1361 {
1362 if (LogVar == NULL) {
1363 return NULL;
1364 }
1365 return LogVar->FullName;
1366 }
1367
1368 /**
1369 * ���O�_�C�A���O���J��
1370 * @param[in,out] info.filename �t�@�C���������l
1371 * OK���A�t�@�C�����A�s�v����������free()��������
1372 * @retval TRUE [ok] ����������
1373 * @retval FALSE �L�����Z��������
1374 */
1375 BOOL FLogOpenDialog(HINSTANCE hInst, HWND hWnd, FLogDlgInfo_t *info)
1376 {
1377 LogDlgWork_t *work = (LogDlgWork_t *)calloc(sizeof(LogDlgWork_t), 1);
1378 wchar_t *srcfnameW = FLogGetLogFilename(info->filename);
1379 work->info = info;
1380 work->info->filename = srcfnameW;
1381 work->pts = &ts;
1382 INT_PTR ret = TTDialogBoxParam(
1383 hInst, MAKEINTRESOURCE(IDD_LOGDLG),
1384 hWnd, LogFnHook, (LPARAM)work);
1385 free(srcfnameW);
1386 free(work);
1387 return ret == IDOK ? TRUE : FALSE;
1388 }
1389
1390 /**
1391 * ���O�t�@�C����������
1392 * ���O�t�@�C�����p���C�����s��
1393 * - strftime() ���������t�W�J
1394 * - �������������O�t�@�C���t�H���_������
1395 * - �z�X�g��,�|�[�g�����W�J
1396 *
1397 * @param[in] log_filename �t�@�C����(����/��������������ok)
1398 * NULL�������f�t�H���g�t�@�C����������
1399 * strftime�`��ok
1400 * @return �t���p�X�t�@�C����
1401 * �s�v���������� free() ��������
1402 */
1403 wchar_t *FLogGetLogFilename(const wchar_t *log_filename)
1404 {
1405 // �t�H���_
1406 char FileDirExpanded[MAX_PATH];
1407 const char *logdir;
1408 if (strlen(ts.LogDefaultPath) > 0) {
1409 logdir = ts.LogDefaultPath;
1410 }
1411 else if (strlen(ts.FileDir) > 0) {
1412 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1413 logdir = FileDirExpanded;
1414 }
1415 else {
1416 logdir = ts.HomeDir;
1417 }
1418
1419 // ���������t�@�C����
1420 char base_name[MAX_PATH];
1421 if (log_filename == NULL) {
1422 strncpy_s(base_name, _countof(base_name), ts.LogDefaultName, _TRUNCATE);
1423 }
1424 else {
1425 char *filenameA = ToCharW(log_filename);
1426 strncpy_s(base_name, _countof(base_name), filenameA, _TRUNCATE);
1427 free(filenameA);
1428 }
1429
1430 // �t���p�X��
1431 char full_path[MAX_PATH];
1432 ConvFName(logdir, base_name, sizeof(base_name), "", full_path, sizeof(full_path));
1433 ParseStrftimeFileName(full_path, sizeof(full_path));
1434 ConvertLogname(full_path, sizeof(full_path));
1435
1436 return ToWcharA(full_path);
1437 }
1438
1439 BOOL FLogIsPause()
1440 {
1441 if (LogVar == NULL) {
1442 return FALSE;
1443 }
1444 return LogVar->IsPause;
1445 }
1446
1447 void FLogWindow(int nCmdShow)
1448 {
1449 if (LogVar == NULL) {
1450 return;
1451 }
1452
1453 HWND HWndLog = LogVar->FLogDlg->m_hWnd;
1454 ShowWindow(HWndLog, nCmdShow);
1455 if (nCmdShow == SW_RESTORE) {
1456 // �g���X�^�C�� WS_EX_NOACTIVATE ��������������
1457 SetForegroundWindow(HWndLog);
1458 }
1459 }
1460
1461 void FLogShowDlg(void)
1462 {
1463 if (LogVar == NULL) {
1464 return;
1465 }
1466 HWND HWndLog = LogVar->FLogDlg->m_hWnd;
1467 ShowWindow(HWndLog, SW_SHOWNORMAL);
1468 SetForegroundWindow(HWndLog);
1469 }
1470
1471 /**
1472 * ���O��1byte��������
1473 * LogPut1() ������?
1474 */
1475 //void Log1Bin(PComVar cv, BYTE b)
1476 static void Log1Bin(BYTE b)
1477 {
1478 if (LogVar->IsPause || cv.ProtoFlag) {
1479 return;
1480 }
1481 if (cv.BinSkip > 0) {
1482 cv.BinSkip--;
1483 return;
1484 }
1485 cv.BinBuf[cv.BinPtr] = b;
1486 cv.BinPtr++;
1487 if (cv.BinPtr>=InBuffSize) {
1488 cv.BinPtr = cv.BinPtr-InBuffSize;
1489 }
1490 if (cv.BCount>=InBuffSize) {
1491 cv.BCount = InBuffSize;
1492 cv.BStart = cv.BinPtr;
1493 }
1494 else {
1495 cv.BCount++;
1496 }
1497 }
1498
1499 static void LogBinSkip(int add)
1500 {
1501 if (cv.HBinBuf!=0 ) {
1502 cv.BinSkip += add;
1503 }
1504 }
1505
1506 /**
1507 * ���O�o�b�t�@���������������f�[�^���o�C�g��������
1508 */
1509 int FLogGetCount(void)
1510 {
1511 if (FileLog) {
1512 return cv.LCount;
1513 }
1514 if (BinLog) {
1515 return cv.BCount;
1516 }
1517 return 0;
1518 }
1519
1520 /**
1521 * �o�b�t�@�������O���t�@�C������������
1522 */
1523 void FLogWriteFile(void)
1524 {
1525 if (cv.LogBuf!=NULL)
1526 {
1527 if (FileLog) {
1528 LogToFile();
1529 }
1530 GlobalUnlock(cv.HLogBuf);
1531 cv.LogBuf = NULL;
1532 }
1533
1534 if (cv.BinBuf!=NULL)
1535 {
1536 if (BinLog) {
1537 LogToFile();
1538 }
1539 GlobalUnlock(cv.HBinBuf);
1540 cv.BinBuf = NULL;
1541 }
1542 }

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