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 8895 - (hide annotations) (download) (as text)
Tue Aug 18 15:27:38 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: 40298 byte(s)
ファイル転送ダイアログ(ftdlg)を汎用的に使用できるよう修正

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

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