Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ttcomtester/teraterm/teraterm/filesys_log.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8905 - (hide annotations) (download) (as text)
Tue Aug 18 15:31:25 2020 UTC (3 years, 7 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/filesys_log.cpp
File MIME type: text/x-c++src
File size: 39997 byte(s)
コメントの書き込みを Unicode 化した

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

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