Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/filesys_log.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8904 - (hide annotations) (download) (as text)
Tue Aug 18 15:31:14 2020 UTC (3 years, 7 months ago) by zmatsuo
File MIME type: text/x-c++src
File size: 40492 byte(s)
ログファイルへの文字コードの変換を filesys_log で行うようにした

- filesys_log へ追加 (vtterm.c から移動)
  - FLogPutUTF32()
  - FLogSetCode()
  - FLogOutputBOM()
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 yutakapon 5206
118 maya 3227
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     // �R�����g�����O����������
856 zmatsuo 8852 static void CommentLogToFile(char *buf, int size)
857 maya 3227 {
858     DWORD wrote;
859    
860 zmatsuo 8901 if (LogVar == NULL) {
861 maya 3227 char uimsg[MAX_UIMSG];
862     get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
863     get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
864     "It is not opened by the log file yet.", ts.UILanguageFile);
865     ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
866     return;
867     }
868    
869     logfile_lock();
870 zmatsuo 7930 WriteFile(LogVar->FileHandle, buf, size, &wrote, NULL);
871     WriteFile(LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
872 maya 3227 /* Set Line End Flag
873     2007.05.24 Gentaro
874     */
875 zmatsuo 8901 LogVar->eLineEnd = Line_LineHead;
876 maya 3227 logfile_unlock();
877     }
878    
879 yutakapon 5162 // ���O�����[�e�[�g�����B
880     // (2013.3.21 yutaka)
881     static void LogRotate(void)
882     {
883 yutakapon 5165 int loopmax = 10000; // XXX
884     int i, k;
885 yutakapon 5162
886     if (LogVar->RotateMode == ROTATE_NONE)
887     return;
888    
889     if (LogVar->RotateMode == ROTATE_SIZE) {
890 doda 6435 if (LogVar->ByteCount <= LogVar->RotateSize)
891 yutakapon 5162 return;
892     //OutputDebugPrintf("%s: mode %d size %ld\n", __FUNCTION__, LogVar->RotateMode, LogVar->ByteCount);
893     } else {
894     return;
895     }
896    
897     logfile_lock();
898     // ���O�T�C�Y���������������B
899     LogVar->ByteCount = 0;
900    
901     // �������������t�@�C�����N���[�Y�����A�������t�@�C�����I�[�v�������B
902 yutakapon 5206 CloseFileSync(LogVar);
903 yutakapon 5162
904 yutakapon 5165 // �������[�e�[�V�������X�e�b�v�����w����������
905     if (LogVar->RotateStep > 0)
906     loopmax = LogVar->RotateStep;
907    
908     for (i = 1 ; i <= loopmax ; i++) {
909 zmatsuo 8899 wchar_t *filename;
910     aswprintf(&filename, L"%s.%d", LogVar->FullName, i);
911     DWORD attr = _GetFileAttributesW(filename);
912     free(filename);
913 zmatsuo 8901 if (attr == INVALID_FILE_ATTRIBUTES)
914 yutakapon 5162 break;
915     }
916 yutakapon 5165 if (i > loopmax) {
917     // �������������������������A�������t�@�C�������p�������B
918     i = loopmax;
919 yutakapon 5162 }
920    
921     // ���t�@�C�������l�[���B
922 yutakapon 5165 for (k = i-1 ; k >= 0 ; k--) {
923 zmatsuo 8899 wchar_t *oldfile;
924 yutakapon 5165 if (k == 0)
925 zmatsuo 8899 oldfile = _wcsdup(LogVar->FullName);
926 yutakapon 5165 else
927 zmatsuo 8899 aswprintf(&oldfile, L"%s.%d", LogVar->FullName, k);
928     wchar_t *newfile;
929     aswprintf(&newfile, L"%s.%d", LogVar->FullName, k+1);
930     _DeleteFileW(newfile);
931     if (_MoveFileW(oldfile, newfile) == 0) {
932 yutakapon 5165 OutputDebugPrintf("%s: rename %d\n", __FUNCTION__, errno);
933     }
934 zmatsuo 8899 free(oldfile);
935     free(newfile);
936 yutakapon 5165 }
937 yutakapon 5162
938     // ���I�[�v��
939 zmatsuo 8901 OpenLogFile(LogVar);
940     if (ts.DeferredLogWriteMode) {
941     StartThread(LogVar);
942 yutakapon 5162 }
943    
944     logfile_unlock();
945     }
946    
947 zmatsuo 8897 /**
948     * �o�b�t�@�������O���t�@�C������������
949     */
950     static void LogToFile(void)
951 maya 3227 {
952     PCHAR Buf;
953     int Start, Count;
954     BYTE b;
955 yutakapon 5206 PCHAR WriteBuf;
956     DWORD WriteBufMax, WriteBufLen;
957     CHAR tmp[128];
958 maya 5273 DWORD wrote;
959 zmatsuo 8901 PFileVar fv = LogVar;
960 maya 3227
961     if (FileLog)
962     {
963     Buf = cv.LogBuf;
964     Start = cv.LStart;
965     Count = cv.LCount;
966     }
967     else if (BinLog)
968     {
969     Buf = cv.BinBuf;
970     Start = cv.BStart;
971     Count = cv.BCount;
972     }
973     else
974     return;
975    
976     if (Buf==NULL) return;
977     if (Count==0) return;
978    
979     // ���b�N������(2004.8.6 yutaka)
980     logfile_lock();
981    
982 yutakapon 5206 if (ts.DeferredLogWriteMode) {
983     WriteBufMax = 8192;
984     WriteBufLen = 0;
985     WriteBuf = (PCHAR)malloc(WriteBufMax);
986     while (Get1(Buf,&Start,&Count,&b)) {
987 zmatsuo 8857 if (!FLogIsPause() && (! cv.ProtoFlag))
988 yutakapon 5206 {
989     tmp[0] = 0;
990 zmatsuo 8901 if ( ts.LogTimestamp && fv->eLineEnd ) {
991 doda 6947 char *strtime = NULL;
992    
993     switch (ts.LogTimestampType) {
994     case TIMESTAMP_LOCAL:
995     strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
996     break;
997     case TIMESTAMP_UTC:
998     strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
999     break;
1000     case TIMESTAMP_ELAPSED_LOGSTART:
1001     strtime = strelapsed(LogVar->StartTime);
1002     break;
1003     case TIMESTAMP_ELAPSED_CONNECTED:
1004     strtime = strelapsed(cv.ConnectedTime);
1005     break;
1006     }
1007    
1008 yutakapon 5206 /* 2007.05.24 Gentaro */
1009 zmatsuo 8901 if(fv->eLineEnd == Line_FileHead ){
1010 yutakapon 5206 strncat_s(tmp, sizeof(tmp), "\r\n", _TRUNCATE);
1011     }
1012     strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE);
1013     strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE);
1014     strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE);
1015     }
1016 doda 6435
1017 yutakapon 5206 /* 2007.05.24 Gentaro */
1018     if( b == 0x0a ){
1019 zmatsuo 8901 fv->eLineEnd = Line_LineHead; /* set endmark*/
1020 yutakapon 5206 }
1021     else {
1022 zmatsuo 8901 fv->eLineEnd = Line_Other; /* clear endmark*/
1023 yutakapon 5206 }
1024    
1025     if (WriteBufLen >= (WriteBufMax*4/5)) {
1026     WriteBufMax *= 2;
1027     WriteBuf = (PCHAR)realloc(WriteBuf, WriteBufMax);
1028     }
1029     memcpy(&WriteBuf[WriteBufLen], tmp, strlen(tmp));
1030     WriteBufLen += strlen(tmp);
1031     WriteBuf[WriteBufLen++] = b;
1032    
1033     (LogVar->ByteCount)++;
1034     }
1035     }
1036    
1037     PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)WriteBuf, WriteBufLen);
1038    
1039     } else {
1040    
1041     while (Get1(Buf,&Start,&Count,&b))
1042 maya 3227 {
1043 zmatsuo 8857 if (!FLogIsPause() && (! cv.ProtoFlag))
1044 yutakapon 5206 {
1045 zmatsuo 8901 if ( ts.LogTimestamp && fv->eLineEnd ) {
1046 doda 6947 char *strtime = NULL;
1047    
1048     switch (ts.LogTimestampType) {
1049     case TIMESTAMP_LOCAL:
1050     strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1051     break;
1052     case TIMESTAMP_UTC:
1053     strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1054     break;
1055     case TIMESTAMP_ELAPSED_LOGSTART:
1056     strtime = strelapsed(LogVar->StartTime);
1057     break;
1058     case TIMESTAMP_ELAPSED_CONNECTED:
1059     strtime = strelapsed(cv.ConnectedTime);
1060     break;
1061     }
1062 zmatsuo 7930 WriteFile(LogVar->FileHandle, "[", 1, &wrote, NULL);
1063     WriteFile(LogVar->FileHandle, strtime, strlen(strtime), &wrote, NULL);
1064     WriteFile(LogVar->FileHandle, "] ", 2, &wrote, NULL);
1065 yutakapon 5206 }
1066 doda 6435
1067 maya 3227 /* 2007.05.24 Gentaro */
1068 yutakapon 5206 if( b == 0x0a ){
1069 zmatsuo 8901 fv->eLineEnd = Line_LineHead; /* set endmark*/
1070 maya 3227 }
1071 yutakapon 5206 else {
1072 zmatsuo 8901 fv->eLineEnd = Line_Other; /* clear endmark*/
1073 yutakapon 5206 }
1074    
1075 zmatsuo 7930 WriteFile(LogVar->FileHandle, (PCHAR)&b, 1, &wrote, NULL);
1076 yutakapon 5206 (LogVar->ByteCount)++;
1077 maya 3227 }
1078 yutakapon 5206 }
1079 maya 3227
1080     }
1081    
1082     logfile_unlock();
1083    
1084     if (FileLog)
1085     {
1086     cv.LStart = Start;
1087     cv.LCount = Count;
1088     }
1089     else {
1090     cv.BStart = Start;
1091     cv.BCount = Count;
1092     }
1093 zmatsuo 8857 if (FLogIsPause() || cv.ProtoFlag) return;
1094 zmatsuo 8901 LogVar->FLogDlg->RefreshNum(LogVar->StartTime, LogVar->FileSize, LogVar->ByteCount);
1095 yutakapon 5162
1096 zmatsuo 8896
1097 yutakapon 5162 // ���O�E���[�e�[�g
1098     LogRotate();
1099 maya 3227 }
1100    
1101 zmatsuo 8897 static BOOL CreateLogBuf(void)
1102 maya 3227 {
1103     if (cv.HLogBuf==NULL)
1104     {
1105     cv.HLogBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1106     cv.LogBuf = NULL;
1107     cv.LogPtr = 0;
1108     cv.LStart = 0;
1109     cv.LCount = 0;
1110     }
1111     return (cv.HLogBuf!=NULL);
1112     }
1113    
1114 zmatsuo 8897 static void FreeLogBuf(void)
1115 maya 3227 {
1116 zmatsuo 8860 if ((cv.HLogBuf==NULL) || FileLog)
1117 maya 3227 return;
1118     if (cv.LogBuf!=NULL)
1119     GlobalUnlock(cv.HLogBuf);
1120     GlobalFree(cv.HLogBuf);
1121     cv.HLogBuf = NULL;
1122     cv.LogBuf = NULL;
1123     cv.LogPtr = 0;
1124     cv.LStart = 0;
1125     cv.LCount = 0;
1126     }
1127    
1128 zmatsuo 8897 static BOOL CreateBinBuf(void)
1129 maya 3227 {
1130     if (cv.HBinBuf==NULL)
1131     {
1132     cv.HBinBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1133     cv.BinBuf = NULL;
1134     cv.BinPtr = 0;
1135     cv.BStart = 0;
1136     cv.BCount = 0;
1137     }
1138     return (cv.HBinBuf!=NULL);
1139     }
1140    
1141 zmatsuo 8897 static void FreeBinBuf(void)
1142 maya 3227 {
1143     if ((cv.HBinBuf==NULL) || BinLog)
1144     return;
1145     if (cv.BinBuf!=NULL)
1146     GlobalUnlock(cv.HBinBuf);
1147     GlobalFree(cv.HBinBuf);
1148     cv.HBinBuf = NULL;
1149     cv.BinBuf = NULL;
1150     cv.BinPtr = 0;
1151     cv.BStart = 0;
1152     cv.BCount = 0;
1153     }
1154    
1155 zmatsuo 8897 static void FileTransEnd_(void)
1156 maya 3227 {
1157 zmatsuo 8900 if (LogVar == NULL) {
1158     return;
1159     }
1160 zmatsuo 8897 FileLog = FALSE;
1161     BinLog = FALSE;
1162     cv.Log1Byte = NULL;
1163     cv.Log1Bin = NULL;
1164     cv.LogBinSkip = NULL;
1165 zmatsuo 8901 PFileTransDlg FLogDlg = LogVar->FLogDlg;
1166     if (FLogDlg != NULL) {
1167 zmatsuo 8897 FLogDlg->DestroyWindow();
1168     FLogDlg = NULL;
1169 maya 3227 }
1170 zmatsuo 8900 CloseFileSync(LogVar);
1171 zmatsuo 8897 FreeLogBuf();
1172     FreeBinBuf();
1173 zmatsuo 8900 free(LogVar);
1174     LogVar = NULL;
1175 maya 3227 }
1176    
1177 zmatsuo 8857 /**
1178     * ���O���|�[�Y����
1179     */
1180     void FLogPause(BOOL Pause)
1181 maya 3227 {
1182 zmatsuo 8899 if (LogVar == NULL) {
1183     return;
1184     }
1185 zmatsuo 8900 LogVar->IsPause = Pause;
1186 zmatsuo 8901 LogVar->FLogDlg->ChangeButton(Pause);
1187 maya 3227 }
1188    
1189 zmatsuo 8857 /**
1190 zmatsuo 8852 * ���O���[�e�[�g������
1191     * ���O���T�C�Y��<size>�o�C�g���������������A���[�e�[�V��������������������
1192     */
1193 zmatsuo 8858 void FLogRotateSize(size_t size)
1194 zmatsuo 8852 {
1195     if (LogVar == NULL) {
1196     return;
1197     }
1198     LogVar->RotateMode = ROTATE_SIZE;
1199     LogVar->RotateSize = size;
1200     }
1201    
1202     /**
1203     * ���O���[�e�[�g������
1204     * ���O�t�@�C������������������
1205     */
1206 zmatsuo 8858 void FLogRotateRotate(int step)
1207 zmatsuo 8852 {
1208     if (LogVar == NULL) {
1209     return;
1210     }
1211     LogVar->RotateStep = step;
1212     }
1213    
1214     /**
1215     * ���O���[�e�[�g������
1216     * ���[�e�[�V���������~
1217     */
1218 zmatsuo 8858 void FLogRotateHalt(void)
1219 zmatsuo 8852 {
1220     if (LogVar == NULL) {
1221     return;
1222     }
1223     LogVar->RotateMode = ROTATE_NONE;
1224     LogVar->RotateSize = 0;
1225     LogVar->RotateStep = 0;
1226     }
1227    
1228     static INT_PTR CALLBACK OnCommentDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp)
1229     {
1230     static const DlgTextInfo TextInfos[] = {
1231     { 0, "DLG_COMMENT_TITLE" },
1232     { IDOK, "BTN_OK" }
1233     };
1234     UINT ret;
1235    
1236     switch (msg) {
1237     case WM_INITDIALOG:
1238     //SetDlgItemText(hDlgWnd, IDC_EDIT_COMMENT, "�T���v��");
1239     // �G�f�B�b�g�R���g���[�����t�H�[�J�X��������
1240     SetFocus(GetDlgItem(hDlgWnd, IDC_EDIT_COMMENT));
1241     SetDlgTexts(hDlgWnd, TextInfos, _countof(TextInfos), ts.UILanguageFile);
1242     return FALSE;
1243    
1244     case WM_COMMAND:
1245     switch (LOWORD(wp)) {
1246 zmatsuo 8901 case IDOK: {
1247     char buf[256];
1248 zmatsuo 8852 memset(buf, 0, sizeof(buf));
1249     ret = GetDlgItemTextA(hDlgWnd, IDC_EDIT_COMMENT, buf, sizeof(buf) - 1);
1250     if (ret > 0) { // �e�L�X�g��������
1251     //buf[sizeof(buf) - 1] = '\0'; // null-terminate
1252     CommentLogToFile(buf, ret);
1253     }
1254     TTEndDialog(hDlgWnd, IDOK);
1255     break;
1256 zmatsuo 8901 }
1257 zmatsuo 8852 default:
1258     return FALSE;
1259     }
1260     break;
1261     case WM_CLOSE:
1262     TTEndDialog(hDlgWnd, 0);
1263     return TRUE;
1264    
1265     default:
1266     return FALSE;
1267     }
1268     return TRUE;
1269     }
1270    
1271 zmatsuo 8858 void FLogAddCommentDlg(HINSTANCE hInst, HWND hWnd)
1272 zmatsuo 8852 {
1273     // ���O�t�@�C�����R�����g���������� (2004.8.6 yutaka)
1274     TTDialogBox(hInst, MAKEINTRESOURCE(IDD_COMMENT_DIALOG),
1275     HVTWin, OnCommentDlgProc);
1276     }
1277    
1278 zmatsuo 8858 void FLogClose(void)
1279 zmatsuo 8852 {
1280 zmatsuo 8897 if (LogVar == NULL) {
1281     return;
1282     }
1283    
1284     FileTransEnd_();
1285 zmatsuo 8852 }
1286    
1287 zmatsuo 8897 /**
1288     * ���O���I�[�v������
1289     * @param[in] fname ���O�t�@�C����, CreateFile()���n������
1290     *
1291     * ���O�t�@�C������strftime���W�J�������s���������B
1292     * FLogGetLogFilename() �� FLogOpenDialog() ��
1293     * �t�@�C�����������������B
1294     */
1295 zmatsuo 8899 BOOL FLogOpen(const wchar_t *fname)
1296 zmatsuo 8852 {
1297     BOOL ret;
1298    
1299 zmatsuo 8894 if (LogVar != NULL) {
1300 zmatsuo 8852 return FALSE;
1301     }
1302 zmatsuo 8897 if ((FileLog) || (BinLog)) return FALSE;
1303 zmatsuo 8852
1304 zmatsuo 8897 //
1305     PFileVar fv = (PFileVar)malloc(sizeof(TFileVar));
1306     if (fv == NULL) {
1307     return FALSE;
1308     }
1309     LogVar = fv;
1310     memset(fv, 0, sizeof(TFileVar));
1311 zmatsuo 8901 fv->FileHandle = INVALID_HANDLE_VALUE;
1312     fv->LogThread = INVALID_HANDLE_VALUE;
1313     fv->eLineEnd = Line_LineHead;
1314 zmatsuo 8904 fv->log_code = 0; // UTF-8
1315 zmatsuo 8897
1316 zmatsuo 8901 ret = LogStart(fname);
1317     if (ret == FALSE) {
1318     FileTransEnd_();
1319     }
1320 zmatsuo 8897
1321 zmatsuo 8852 return ret;
1322     }
1323    
1324 zmatsuo 8858 BOOL FLogIsOpend(void)
1325 zmatsuo 8852 {
1326     return LogVar != NULL;
1327     }
1328    
1329 zmatsuo 8904 BOOL FLogIsOpendText(void)
1330     {
1331     return LogVar != NULL && FileLog;
1332     }
1333    
1334     BOOL FLogIsOpendBin(void)
1335     {
1336     return LogVar != NULL && BinLog;
1337     }
1338    
1339 zmatsuo 8858 void FLogWriteStr(const char *str)
1340 zmatsuo 8852 {
1341     if (LogVar != NULL)
1342     {
1343     DWORD wrote;
1344     size_t len = strlen(str);
1345     WriteFile(LogVar->FileHandle, str, len, &wrote, NULL);
1346     LogVar->ByteCount =
1347     LogVar->ByteCount + len;
1348 zmatsuo 8901 LogVar->FLogDlg->RefreshNum(LogVar->StartTime, LogVar->FileSize, LogVar->ByteCount);
1349 zmatsuo 8852 }
1350     }
1351    
1352 zmatsuo 8858 void FLogInfo(char *param_ptr, size_t param_len)
1353 zmatsuo 8852 {
1354     if (LogVar) {
1355     param_ptr[0] = '0'
1356     + (ts.LogBinary != 0)
1357     + ((ts.Append != 0) << 1)
1358     + ((ts.LogTypePlainText != 0) << 2)
1359     + ((ts.LogTimestamp != 0) << 3)
1360     + ((ts.LogHideDialog != 0) << 4);
1361 zmatsuo 8899 char *filenameU8 = ToU8W(LogVar->FullName);
1362     strncpy_s(param_ptr + 1, param_len - 1, filenameU8, _TRUNCATE);
1363     free(filenameU8);
1364 zmatsuo 8852 }
1365     else {
1366     param_ptr[0] = '0' - 1;
1367     param_ptr[1] = 0;
1368     }
1369     }
1370    
1371     /**
1372     * ���������O�t�@�C����������
1373     */
1374 zmatsuo 8899 const wchar_t *FLogGetFilename(void)
1375 zmatsuo 8852 {
1376     if (LogVar == NULL) {
1377     return NULL;
1378     }
1379     return LogVar->FullName;
1380     }
1381    
1382     /**
1383     * ���O�_�C�A���O���J��
1384 zmatsuo 8863 * @param[in,out] info.filename �t�@�C���������l
1385     * OK���A�t�@�C�����A�s�v����������free()��������
1386 zmatsuo 8852 * @retval TRUE [ok] ����������
1387     * @retval FALSE �L�����Z��������
1388     */
1389 zmatsuo 8863 BOOL FLogOpenDialog(HINSTANCE hInst, HWND hWnd, FLogDlgInfo_t *info)
1390 zmatsuo 8852 {
1391 zmatsuo 8863 LogDlgWork_t *work = (LogDlgWork_t *)calloc(sizeof(LogDlgWork_t), 1);
1392 zmatsuo 8899 wchar_t *srcfnameW = FLogGetLogFilename(info->filename);
1393 zmatsuo 8863 work->info = info;
1394     work->info->filename = srcfnameW;
1395     work->pts = &ts;
1396 zmatsuo 8852 INT_PTR ret = TTDialogBoxParam(
1397     hInst, MAKEINTRESOURCE(IDD_LOGDLG),
1398 zmatsuo 8863 hWnd, LogFnHook, (LPARAM)work);
1399     free(srcfnameW);
1400     free(work);
1401 zmatsuo 8852 return ret == IDOK ? TRUE : FALSE;
1402     }
1403    
1404     /**
1405     * ���O�t�@�C����������
1406     * ���O�t�@�C�����p���C�����s��
1407     * - strftime() ���������t�W�J
1408     * - �������������O�t�@�C���t�H���_������
1409     * - �z�X�g��,�|�[�g�����W�J
1410     *
1411     * @param[in] log_filename �t�@�C����(����/��������������ok)
1412     * NULL�������f�t�H���g�t�@�C����������
1413     * strftime�`��ok
1414     * @return �t���p�X�t�@�C����
1415     * �s�v���������� free() ��������
1416     */
1417 zmatsuo 8899 wchar_t *FLogGetLogFilename(const wchar_t *log_filename)
1418 zmatsuo 8852 {
1419     // �t�H���_
1420     char FileDirExpanded[MAX_PATH];
1421 zmatsuo 8899 const char *logdir;
1422 zmatsuo 8852 if (strlen(ts.LogDefaultPath) > 0) {
1423     logdir = ts.LogDefaultPath;
1424     }
1425     else if (strlen(ts.FileDir) > 0) {
1426     ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1427     logdir = FileDirExpanded;
1428     }
1429     else {
1430     logdir = ts.HomeDir;
1431     }
1432    
1433     // ���������t�@�C����
1434     char base_name[MAX_PATH];
1435     if (log_filename == NULL) {
1436     strncpy_s(base_name, _countof(base_name), ts.LogDefaultName, _TRUNCATE);
1437     }
1438     else {
1439 zmatsuo 8899 char *filenameA = ToCharW(log_filename);
1440     strncpy_s(base_name, _countof(base_name), filenameA, _TRUNCATE);
1441     free(filenameA);
1442 zmatsuo 8852 }
1443    
1444     // �t���p�X��
1445     char full_path[MAX_PATH];
1446     ConvFName(logdir, base_name, sizeof(base_name), "", full_path, sizeof(full_path));
1447     ParseStrftimeFileName(full_path, sizeof(full_path));
1448     ConvertLogname(full_path, sizeof(full_path));
1449    
1450 zmatsuo 8899 return ToWcharA(full_path);
1451 zmatsuo 8852 }
1452 zmatsuo 8857
1453     BOOL FLogIsPause()
1454     {
1455 zmatsuo 8900 if (LogVar == NULL) {
1456     return FALSE;
1457     }
1458     return LogVar->IsPause;
1459 zmatsuo 8857 }
1460    
1461     void FLogWindow(int nCmdShow)
1462     {
1463 zmatsuo 8900 if (LogVar == NULL) {
1464     return;
1465     }
1466 zmatsuo 8857
1467 zmatsuo 8901 HWND HWndLog = LogVar->FLogDlg->m_hWnd;
1468 zmatsuo 8857 ShowWindow(HWndLog, nCmdShow);
1469     if (nCmdShow == SW_RESTORE) {
1470     // �g���X�^�C�� WS_EX_NOACTIVATE ��������������
1471     SetForegroundWindow(HWndLog);
1472     }
1473     }
1474    
1475     void FLogShowDlg(void)
1476     {
1477 zmatsuo 8900 if (LogVar == NULL) {
1478     return;
1479     }
1480 zmatsuo 8901 HWND HWndLog = LogVar->FLogDlg->m_hWnd;
1481     ShowWindow(HWndLog, SW_SHOWNORMAL);
1482     SetForegroundWindow(HWndLog);
1483 zmatsuo 8857 }
1484 zmatsuo 8897
1485     /**
1486     * ���O��1byte��������
1487     * LogPut1() ������?
1488     */
1489     //void Log1Bin(PComVar cv, BYTE b)
1490     static void Log1Bin(BYTE b)
1491     {
1492 zmatsuo 8900 if (LogVar->IsPause || cv.ProtoFlag) {
1493 zmatsuo 8897 return;
1494     }
1495     if (cv.BinSkip > 0) {
1496     cv.BinSkip--;
1497     return;
1498     }
1499     cv.BinBuf[cv.BinPtr] = b;
1500     cv.BinPtr++;
1501     if (cv.BinPtr>=InBuffSize) {
1502     cv.BinPtr = cv.BinPtr-InBuffSize;
1503     }
1504     if (cv.BCount>=InBuffSize) {
1505     cv.BCount = InBuffSize;
1506     cv.BStart = cv.BinPtr;
1507     }
1508     else {
1509     cv.BCount++;
1510     }
1511     }
1512    
1513     static void LogBinSkip(int add)
1514     {
1515     if (cv.HBinBuf!=0 ) {
1516     cv.BinSkip += add;
1517     }
1518     }
1519    
1520     /**
1521     * ���O�o�b�t�@���������������f�[�^���o�C�g��������
1522     */
1523     int FLogGetCount(void)
1524     {
1525     if (FileLog) {
1526     return cv.LCount;
1527     }
1528     if (BinLog) {
1529     return cv.BCount;
1530     }
1531     return 0;
1532     }
1533    
1534     /**
1535     * �o�b�t�@�������O���t�@�C������������
1536     */
1537     void FLogWriteFile(void)
1538     {
1539     if (cv.LogBuf!=NULL)
1540     {
1541     if (FileLog) {
1542     LogToFile();
1543     }
1544     GlobalUnlock(cv.HLogBuf);
1545     cv.LogBuf = NULL;
1546     }
1547    
1548     if (cv.BinBuf!=NULL)
1549     {
1550     if (BinLog) {
1551     LogToFile();
1552     }
1553     GlobalUnlock(cv.HBinBuf);
1554     cv.BinBuf = NULL;
1555     }
1556     }
1557 zmatsuo 8904
1558     void FLogPutUTF32(unsigned int u32)
1559     {
1560     PFileVar fv = LogVar;
1561     size_t i;
1562     BOOL log_available = (cv.HLogBuf != 0);
1563    
1564     if (!log_available) {
1565     // ���O�����o��������(macro�o������������)
1566     return;
1567     }
1568    
1569     switch(fv->log_code) {
1570     case 0: {
1571     // UTF-8
1572     char u8_buf[4];
1573     size_t u8_len = UTF32ToUTF8(u32, u8_buf, _countof(u8_buf));
1574     for (i = 0; i < u8_len; i++) {
1575     BYTE b = u8_buf[i];
1576     LogPut1(b);
1577     }
1578     break;
1579     }
1580     case 1:
1581     case 2: {
1582     // UTF-16
1583     wchar_t u16[2];
1584     size_t u16_len = UTF32ToUTF16(u32, u16, _countof(u16));
1585     size_t i;
1586     for (i = 0; i < u16_len; i++) {
1587     if (fv->log_code == 1) {
1588     // UTF-16LE
1589     LogPut1(u16[i] & 0xff);
1590     LogPut1((u16[i] >> 8) & 0xff);
1591     }
1592     else {
1593     // UTF-16BE
1594     LogPut1((u16[i] >> 8) & 0xff);
1595     LogPut1(u16[i] & 0xff);
1596     }
1597     }
1598     }
1599     }
1600     }
1601    
1602     void FLogOutputBOM(void)
1603     {
1604     PFileVar fv = LogVar;
1605     BOOL needs_unlock = FALSE;
1606    
1607     if ((cv.HLogBuf!=NULL) && (cv.LogBuf==NULL)) {
1608     cv.LogBuf = (PCHAR)GlobalLock(cv.HLogBuf);
1609     needs_unlock = TRUE;
1610     }
1611    
1612     switch(fv->log_code) {
1613     case 0:
1614     // UTF-8
1615     LogPut1(0xef);
1616     LogPut1(0xbb);
1617     LogPut1(0xbf);
1618     break;
1619     case 1:
1620     // UTF-16LE
1621     LogPut1(0xfe);
1622     LogPut1(0xff);
1623     break;
1624     case 2:
1625     // UTF-16BE
1626     LogPut1(0xff);
1627     LogPut1(0xfe);
1628     break;
1629     default:
1630     break;
1631     }
1632    
1633     if (needs_unlock) {
1634     GlobalUnlock(cv.HLogBuf);
1635     cv.LogBuf = NULL;
1636     }
1637     }
1638    
1639     void FLogSetCode(int code)
1640     {
1641     PFileVar fv = LogVar;
1642     fv->log_code = code;
1643     }

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