Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/filesys_log.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8895 - (show annotations) (download) (as text)
Tue Aug 18 15:27:38 2020 UTC (3 years, 7 months ago) by zmatsuo
File MIME type: text/x-c++src
File size: 40298 byte(s)
ファイル転送ダイアログ(ftdlg)を汎用的に使用できるよう修正

- メンバ変数から PFileVar をなくした
  - TFile(PVarPFileVar), TTTSet, TComVar なしで使用可
- 従来と同等のAPIも残した
1 /*
2 * (C) 2020 TeraTerm Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /* TERATERM.EXE, file transfer routines */
30 #include <stdio.h>
31 #include <io.h>
32 #include <process.h>
33 #include <windows.h>
34 #include <htmlhelp.h>
35 #include <assert.h>
36
37 #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 #include "vtterm.h"
47 #include "ftlib.h"
48 #include "buffer.h"
49 #include "helpid.h"
50 #include "layer_for_unicode.h"
51 #include "layer_for_unicode_crt.h"
52 #include "codeconv.h"
53
54 #include "filesys_log_res.h"
55 #include "filesys.h"
56
57 #if 0
58 typedef struct {
59 HWND HMainWin;
60 HWND HWin;
61 WORD OpId;
62 char DlgCaption[40];
63
64 char FullName[MAX_PATH];
65 int DirLen;
66
67 int NumFname, FNCount;
68 HANDLE FnStrMemHandle;
69 PCHAR FnStrMem;
70 int FnPtr;
71
72 BOOL FileOpen;
73 HANDLE FileHandle;
74 LONG FileSize, ByteCount;
75 BOOL OverWrite;
76
77 BOOL LogFlag;
78 HANDLE LogFile;
79 WORD LogState;
80 WORD LogCount;
81
82 BOOL Success;
83 BOOL NoMsg;
84
85 char LogDefaultPath[MAX_PATH];
86 BOOL HideDialog;
87
88 BYTE LogLineBuf[16];
89 int FlushLogLineBuf;
90
91 int ProgStat;
92
93 DWORD StartTime;
94
95 // log rotate
96 int RotateMode; // enum rotate_mode RotateMode;
97 LONG RotateSize;
98 int RotateStep;
99
100 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 /*
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 static enum enumLineEnd eLineEnd = Line_LineHead;
128
129
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 static void FileTransEnd_(WORD OpId);
135
136
137 static PFileTransDlg FLogDlg = NULL;
138
139 static BOOL OpenFTDlg_(PFileVar fv)
140 {
141 PFileTransDlg FTDlg;
142
143 FTDlg = new CFileTransDlg();
144
145 fv->StartTime = 0;
146 fv->ProgStat = 0;
147 cv.FilePause &= ~fv->OpId;
148
149 if (fv->OpId != OpLog) {
150 fv->HideDialog = ts.FTHideDialog;
151 }
152
153 if (FTDlg!=NULL)
154 {
155 FTDlg->Create(hInst, HVTWin, fv, &cv, &ts);
156 FTDlg->RefreshNum(fv);
157 }
158
159 // if (fv->OpId==OpLog)
160 FLogDlg = FTDlg; /* Log */
161 #if 0
162 else
163 SendDlg = FTDlg; /* File send */
164 #endif
165
166 fv->StartTime = GetTickCount();
167
168 return (FTDlg!=NULL);
169 }
170
171 static void ShowFTDlg(WORD OpId)
172 {
173 // if (OpId == OpLog)
174 {
175 if (FLogDlg != NULL) {
176 FLogDlg->ShowWindow(SW_SHOWNORMAL);
177 SetForegroundWindow(FLogDlg->GetSafeHwnd());
178 }
179 }
180 #if 0
181 else {
182 if (SendDlg != NULL) {
183 SendDlg->ShowWindow(SW_SHOWNORMAL);
184 SetForegroundWindow(SendDlg->GetSafeHwnd());
185 }
186 }
187 #endif
188 }
189
190 static BOOL NewFileVar_(PFileVar *fv)
191 {
192 if ((*fv)==NULL)
193 {
194 *fv = (PFileVar)malloc(sizeof(TFileVar));
195 if ((*fv)!=NULL)
196 {
197 char FileDirExpanded[MAX_PATH];
198 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
199 memset(*fv, 0, sizeof(TFileVar));
200 strncpy_s((*fv)->FullName, sizeof((*fv)->FullName), FileDirExpanded, _TRUNCATE);
201 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 static void FreeFileVar_(PFileVar *fv)
216 {
217 if ((*fv)!=NULL)
218 {
219 CloseFileSync(*fv);
220 //if ((*fv)->FileOpen) _lclose((*fv)->FileHandle);
221 if ((*fv)->FnStrMemHandle != 0)
222 {
223 GlobalUnlock((*fv)->FnStrMemHandle);
224 GlobalFree((*fv)->FnStrMemHandle);
225 }
226 free(*fv);
227 *fv = NULL;
228 }
229 }
230
231 /**
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 {
239 char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
240 char tmphost[1024];
241 char tmpuser[256+1];
242 DWORD len_user = sizeof(tmpuser);
243
244 memset(buf, 0, sizeof(buf));
245
246 while(*p != '\0') {
247 if (*p == '&' && *(p+1) != '\0') {
248 switch (*(p+1)) {
249 case 'h':
250 if (cv.Open) {
251 if (cv.PortType == IdTCPIP) {
252 // �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 replaceInvalidFileNameChar(tmphost, '_');
258 strncat_s(buf,sizeof(buf), tmphost, _TRUNCATE);
259 }
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 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 case 'u':
276 if (GetUserName(tmpuser, &len_user) != 0) {
277 strncat_s(buf,sizeof(buf),tmpuser,_TRUNCATE);
278 }
279 break;
280 default:
281 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 static void FixLogOption(void)
296 {
297 if (ts.LogBinary) {
298 ts.LogTypePlainText = false;
299 ts.LogTimestamp = false;
300 }
301 }
302
303
304 // �X���b�h���I�����t�@�C�����N���[�Y
305 static void CloseFileSync(PFileVar ptr)
306 {
307 BOOL ret;
308
309 if (!ptr->FileOpen)
310 return;
311
312 if (ptr->LogThread != INVALID_HANDLE_VALUE) {
313 // �X���b�h���I������
314 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 //DWORD code = GetLastError();
321 }
322 CloseHandle(ptr->LogThread);
323 ptr->LogThread = INVALID_HANDLE_VALUE;
324 }
325 CloseHandle(ptr->FileHandle);
326 }
327
328 // �x�����������p�X���b�h
329 static unsigned _stdcall DeferredLogWriteThread(void *arg)
330 {
331 MSG msg;
332 PFileVar fv = (PFileVar)arg;
333 PCHAR buf;
334 DWORD buflen;
335 DWORD wrote;
336
337 PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
338
339 // �X���b�h�L���[���������I�������������X���b�h�����������m�����B
340 if (fv->LogThreadEvent != NULL) {
341 SetEvent(fv->LogThreadEvent);
342 }
343
344 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 WriteFile(LogVar->FileHandle, buf, buflen, &wrote, NULL);
350 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 /**
365 * �_�C�A���O�����e�� ts ����������
366 *
367 * TODO
368 * �_�C�A���O�����������l�������I��������
369 * ����������������������������������������������?
370 */
371 static void SetLogFlags(HWND Dialog)
372 {
373 WORD BinFlag, val;
374
375 GetRB(Dialog, &BinFlag, IDC_FOPTBIN, IDC_FOPTBIN);
376 ts.LogBinary = BinFlag;
377
378 GetRB(Dialog, &val, IDC_APPEND, IDC_APPEND);
379 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 }
388
389 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 static void CheckLogFile(const wchar_t *filename, BOOL *exist, int *bom)
409 {
410 *exist = FALSE;
411 *bom = 0;
412
413 // �t�@�C������������?
414 DWORD logdir = _GetFileAttributesW(filename);
415 if ((logdir != INVALID_FILE_ATTRIBUTES) && ((logdir & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
416 // �t�@�C����������
417 *exist = TRUE;
418
419 // BOM�L��/�����`�F�b�N
420 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 }
440 }
441 }
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 if (work->pts->Append > 0) {
456 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_APPEND);
457 }
458 }
459 else {
460 // �t�@�C�������� -> �V�K
461 EnableWindow(GetDlgItem(Dialog, IDC_APPEND), FALSE);
462 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_NEW_OVERWRITE);
463 }
464
465 if (work->file_exist && IsDlgButtonChecked(Dialog, IDC_APPEND) == BST_CHECKED) {
466 // �t�@�C������������ && append
467 int bom = work->current_bom;
468 if (bom != 0) {
469 // BOM�L��
470 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
471 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 }
477 else {
478 // BOM����
479 CheckDlgButton(Dialog, IDC_BOM, BST_UNCHECKED);
480 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
481 }
482 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 }
494 else {
495 // �t�@�C�������� ���� append��������(������)
496 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_NEW_OVERWRITE);
497 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
498 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 }
503 }
504
505 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
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 { IDC_APPEND, "DLG_FOPT_APPEND" },
521 { 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 LogDlgWork_t *work = (LogDlgWork_t *)GetWindowLongPtr(Dialog, DWLP_USER);
533
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 work = (LogDlgWork_t *)lParam;
542 TTTSet *pts = work->pts;
543 const char *UILanguageFile = pts->UILanguageFile;
544 SetWindowLongPtr(Dialog, DWLP_USER, (LONG_PTR)work);
545 ::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 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-16LE");
553 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-16BE");
554 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
555
556 _SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, work->info->filename);
557 work->info->filename = NULL;
558
559 // Binary/Text �`�F�b�N�{�b�N�X
560 if (pts->LogBinary) {
561 CheckRadioButton(Dialog, IDC_FOPTBIN, IDC_FOPTTEXT, IDC_FOPTBIN);
562 }
563 else {
564 CheckRadioButton(Dialog, IDC_FOPTBIN, IDC_FOPTTEXT, IDC_FOPTTEXT);
565 }
566
567 // Plain Text �`�F�b�N�{�b�N�X
568 if (pts->LogBinary) {
569 // Binary�t���O���L�����������`�F�b�N��������
570 DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_PLAINTEXT);
571 }
572 else if (pts->LogTypePlainText) {
573 SetRB(Dialog, 1, IDC_PLAINTEXT, IDC_PLAINTEXT);
574 }
575
576 // Hide dialog�`�F�b�N�{�b�N�X (2008.1.30 maya)
577 if (pts->LogHideDialog) {
578 SetRB(Dialog, 1, IDC_HIDEDIALOG, IDC_HIDEDIALOG);
579 }
580
581 // Include screen buffer�`�F�b�N�{�b�N�X (2013.9.29 yutaka)
582 if (pts->LogAllBuffIncludedInFirst) {
583 SetRB(Dialog, 1, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST);
584 }
585
586 // timestamp�`�F�b�N�{�b�N�X (2006.7.23 maya)
587 if (pts->LogBinary) {
588 // Binary�t���O���L�����������`�F�b�N��������
589 DisableDlgItem(Dialog, IDC_TIMESTAMP, IDC_TIMESTAMP);
590 }
591 else if (pts->LogTimestamp) {
592 SetRB(Dialog, 1, IDC_TIMESTAMP, IDC_TIMESTAMP);
593 }
594
595 // timestamp ����
596 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 SendDlgItemMessage(Dialog, IDC_TIMESTAMPTYPE, CB_SETCURSEL, tstype, 0);
601 if (pts->LogBinary || !pts->LogTimestamp) {
602 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 wchar_t filename[MAX_PATH];
614 _GetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
615 work->info->filename = _wcsdup(filename);
616 work->info->append = IsDlgButtonChecked(Dialog, IDC_APPEND) == BST_CHECKED;
617 work->info->bom = IsDlgButtonChecked(Dialog, IDC_BOM) == BST_CHECKED;
618 work->info->code = (int)SendDlgItemMessageA(Dialog, IDC_TEXTCODING_DROPDOWN, CB_GETCURSEL, 0, 0);
619 SetLogFlags(Dialog);
620 EndDialog(Dialog, IDOK);
621 break;
622 }
623 case IDCANCEL:
624 EndDialog(Dialog, IDCANCEL);
625 break;
626 case IDHELP:
627 OpenHelp(HH_HELP_CONTEXT, HlpFileLog, work->pts->UILanguageFile);
628 break;
629 case IDC_FOPT_FILENAME_BUTTON: {
630 /* save current dir */
631 const char *UILanguageFile = work->pts->UILanguageFile;
632 wchar_t curdir[MAXPATHLEN];
633 _GetCurrentDirectoryW(_countof(curdir), curdir);
634
635 wchar_t fname[MAX_PATH];
636 GetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, fname, _countof(fname));
637
638 wchar_t FNFilter[128*3];
639 get_lang_msgW("FILEDLG_ALL_FILTER", FNFilter, sizeof(FNFilter), L"All(*.*)\\0*.*\\0\\0", UILanguageFile);
640
641 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
648 OPENFILENAMEW ofn = {};
649 ofn.lStructSize = get_OPENFILENAME_SIZEW();
650 //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 ofn.nMaxFile = _countof(fname);
659 ofn.lpstrTitle = caption;
660 BOOL Ok = GetSaveFileNameW(&ofn);
661 if (Ok) {
662 SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, fname);
663 }
664
665 /* restore dir */
666 _SetCurrentDirectoryW(curdir);
667
668 break;
669 }
670 case IDC_FOPTBIN:
671 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), FALSE);
672 EnableWindow(GetDlgItem(Dialog, IDC_BOM), FALSE);
673 DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_TIMESTAMP);
674 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
675 break;
676 case IDC_FOPTTEXT:
677 ArrangeControls(Dialog, work);
678 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 }
684 else {
685 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
686 }
687 break;
688 case IDC_FOPT_FILENAME_EDIT:
689 if (HIWORD(wParam) == EN_CHANGE){
690 wchar_t filename[MAX_PATH];
691 GetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
692 CheckLogFile(Dialog, filename, work);
693 }
694 break;
695 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 }
707 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 CheckRadioButton(Dialog, IDC_NEW_OVERWRITE, IDC_APPEND, IDC_APPEND);
720 _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 }
726 }
727 return FALSE;
728 }
729
730 static BOOL LogStart(void)
731 {
732 unsigned tid;
733
734 if ((FileLog) || (BinLog)) return FALSE;
735
736 assert(LogVar != NULL);
737
738 if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0) {
739 // �t�@�C����������������������
740 return FALSE;
741 }
742
743 if (! LoadTTFILE()) return FALSE;
744
745 LogVar->OpId = OpLog;
746 (*SetFileVar)(LogVar);
747 FixLogOption();
748
749 if (ts.LogBinary > 0)
750 {
751 BinLog = TRUE;
752 FileLog = FALSE;
753 if (! CreateBinBuf())
754 {
755 FileTransEnd_(OpLog);
756 return FALSE;
757 }
758 }
759 else {
760 BinLog = FALSE;
761 FileLog = TRUE;
762 if (! CreateLogBuf())
763 {
764 FileTransEnd_(OpLog);
765 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 int dwShareMode = FILE_SHARE_READ;
779 if (!ts.LogLockExclusive) {
780 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
781 }
782 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 /* 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 else {
794 int dwShareMode = FILE_SHARE_READ;
795 if (!ts.LogLockExclusive) {
796 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
797 }
798 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
799 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
800 }
801 LogVar->FileOpen = (LogVar->FileHandle != INVALID_HANDLE_VALUE);
802 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 FileTransEnd_(OpLog);
813 return FALSE;
814 }
815 LogVar->ByteCount = 0;
816
817 // Log rotate configuration
818 LogVar->RotateMode = ts.LogRotate;
819 LogVar->RotateSize = ts.LogRotateSize;
820 LogVar->RotateStep = ts.LogRotateStep;
821
822 // 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 DWORD size = GetFileSize(LogVar->FileHandle, NULL);
827 if (size != -1)
828 LogVar->ByteCount = size;
829 }
830
831 if (! OpenFTDlg_(LogVar)) {
832 FileTransEnd_(OpLog);
833 return FALSE;
834 }
835
836 // �x�����������p�X���b�h���N�����B
837 // (2013.4.19 yutaka)
838 // 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 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
847 LogVar->LogThreadId = tid;
848 if (LogVar->LogThreadEvent != NULL) {
849 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
850 CloseHandle(LogVar->LogThreadEvent);
851 }
852
853 // �����o�b�t�@�������f�[�^�������������o���������A
854 // ���O�������J�n�����B
855 // (2013.9.29 yutaka)
856 if (ts.LogAllBuffIncludedInFirst) {
857 DWORD ofs, size, written_size;
858 char buf[512];
859 const char *crlf = "\r\n";
860 DWORD crlf_len = 2;
861 for (ofs = 0 ; ; ofs++ ) {
862 // 1�����s�����������B���������������A�G�X�P�[�v�V�[�P���X�������������B
863 size = BuffGetAnyLineData(ofs, buf, sizeof(buf));
864 if (size == -1)
865 break;
866
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 WriteFile(LogVar->FileHandle, buf, size, &written_size, NULL);
878 WriteFile(LogVar->FileHandle, crlf, crlf_len, &written_size, NULL);
879 #if 0
880 }
881 #endif
882 }
883 }
884
885 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 static void CommentLogToFile(char *buf, int size)
941 {
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 WriteFile(LogVar->FileHandle, buf, size, &wrote, NULL);
955 WriteFile(LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
956 /* Set Line End Flag
957 2007.05.24 Gentaro
958 */
959 eLineEnd = Line_LineHead;
960 logfile_unlock();
961 }
962
963 // ���O�����[�e�[�g�����B
964 // (2013.3.21 yutaka)
965 static void LogRotate(void)
966 {
967 int loopmax = 10000; // XXX
968 char filename[1024];
969 char newfile[1024], oldfile[1024];
970 int i, k;
971 int dwShareMode = FILE_SHARE_READ;
972 unsigned tid;
973
974 if (! LogVar->FileOpen) return;
975
976 if (LogVar->RotateMode == ROTATE_NONE)
977 return;
978
979 if (LogVar->RotateMode == ROTATE_SIZE) {
980 if (LogVar->ByteCount <= LogVar->RotateSize)
981 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 CloseFileSync(LogVar);
993 //_lclose(LogVar->FileHandle);
994
995 // �������[�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 _snprintf_s(filename, sizeof(filename), _TRUNCATE, "%s.%d", LogVar->FullName, i);
1001 if (_access_s(filename, 0) != 0)
1002 break;
1003 }
1004 if (i > loopmax) {
1005 // �������������������������A�������t�@�C�������p�������B
1006 i = loopmax;
1007 }
1008
1009 // ���t�@�C�������l�[���B
1010 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
1022 // ���I�[�v��
1023 if (!ts.LogLockExclusive) {
1024 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1025 }
1026 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
1027 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1028
1029 // �x�����������p�X���b�h���N�����B
1030 // (2013.4.19 yutaka)
1031 // 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 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
1040 LogVar->LogThreadId = tid;
1041 if (LogVar->LogThreadEvent != NULL) {
1042 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
1043 CloseHandle(LogVar->LogThreadEvent);
1044 }
1045
1046 logfile_unlock();
1047
1048 }
1049
1050 void LogToFile(void)
1051 {
1052 PCHAR Buf;
1053 int Start, Count;
1054 BYTE b;
1055 PCHAR WriteBuf;
1056 DWORD WriteBufMax, WriteBufLen;
1057 CHAR tmp[128];
1058 DWORD wrote;
1059
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 if (ts.DeferredLogWriteMode) {
1083 WriteBufMax = 8192;
1084 WriteBufLen = 0;
1085 WriteBuf = (PCHAR)malloc(WriteBufMax);
1086 while (Get1(Buf,&Start,&Count,&b)) {
1087 if (!FLogIsPause() && (! cv.ProtoFlag))
1088 {
1089 tmp[0] = 0;
1090 if ( ts.LogTimestamp && eLineEnd ) {
1091 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 /* 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
1117 /* 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 {
1143 if (!FLogIsPause() && (! cv.ProtoFlag))
1144 {
1145 if ( ts.LogTimestamp && eLineEnd ) {
1146 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 WriteFile(LogVar->FileHandle, "[", 1, &wrote, NULL);
1163 WriteFile(LogVar->FileHandle, strtime, strlen(strtime), &wrote, NULL);
1164 WriteFile(LogVar->FileHandle, "] ", 2, &wrote, NULL);
1165 }
1166
1167 /* 2007.05.24 Gentaro */
1168 if( b == 0x0a ){
1169 eLineEnd = Line_LineHead; /* set endmark*/
1170 }
1171 else {
1172 eLineEnd = Line_Other; /* clear endmark*/
1173 }
1174
1175 WriteFile(LogVar->FileHandle, (PCHAR)&b, 1, &wrote, NULL);
1176 (LogVar->ByteCount)++;
1177 }
1178 }
1179
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 if (FLogIsPause() || cv.ProtoFlag) return;
1194 if (FLogDlg!=NULL)
1195 FLogDlg->RefreshNum(LogVar);
1196
1197 // ���O�E���[�e�[�g
1198 LogRotate();
1199
1200 }
1201
1202 BOOL CreateLogBuf(void)
1203 {
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 void FreeLogBuf(void)
1216 {
1217 if ((cv.HLogBuf==NULL) || FileLog)
1218 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 BOOL CreateBinBuf(void)
1230 {
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 void FreeBinBuf(void)
1243 {
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 static void FileTransEnd_(WORD OpId)
1257 /* 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 FreeFileVar_(&LogVar);
1271 FreeLogBuf();
1272 FreeBinBuf();
1273 FreeTTFILE();
1274 }
1275
1276 #if 0
1277 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 FreeFileVar_(&SendVar);
1287 FreeTTFILE();
1288 }
1289 #endif
1290
1291 // EndDdeCmnd(0);
1292 }
1293
1294
1295 /**
1296 * ���O���|�[�Y����
1297 * ���� FLogChangeButton() ������
1298 */
1299 void FLogPause(BOOL Pause)
1300 {
1301 if (FLogDlg!=NULL)
1302 FLogDlg->ChangeButton(Pause);
1303 FileTransPause(OpLog, Pause);
1304 }
1305
1306 /**
1307 * ���O���[�e�[�g������
1308 * ���O���T�C�Y��<size>�o�C�g���������������A���[�e�[�V��������������������
1309 */
1310 void FLogRotateSize(size_t size)
1311 {
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 void FLogRotateRotate(int step)
1324 {
1325 if (LogVar == NULL) {
1326 return;
1327 }
1328 LogVar->RotateStep = step;
1329 }
1330
1331 /**
1332 * ���O���[�e�[�g������
1333 * ���[�e�[�V���������~
1334 */
1335 void FLogRotateHalt(void)
1336 {
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 void FLogAddCommentDlg(HINSTANCE hInst, HWND hWnd)
1388 {
1389 // ���O�t�@�C�����R�����g���������� (2004.8.6 yutaka)
1390 TTDialogBox(hInst, MAKEINTRESOURCE(IDD_COMMENT_DIALOG),
1391 HVTWin, OnCommentDlgProc);
1392 }
1393
1394 void FLogClose(void)
1395 {
1396 if (LogVar != NULL)
1397 FileTransEnd_(OpLog);
1398 }
1399
1400 BOOL FLogOpen(const char *fname)
1401 {
1402 BOOL ret;
1403
1404 if (LogVar != NULL) {
1405 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 BOOL FLogIsOpend(void)
1416 {
1417 // LogVar->FileOpen
1418 return LogVar != NULL;
1419 }
1420
1421 void FLogWriteStr(const char *str)
1422 {
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 if (FLogDlg!=NULL)
1431 FLogDlg->RefreshNum(LogVar);
1432 }
1433 }
1434
1435 void FLogInfo(char *param_ptr, size_t param_len)
1436 {
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 const char *FLogGetFilename()
1456 {
1457 if (LogVar == NULL) {
1458 return NULL;
1459 }
1460 return LogVar->FullName;
1461 }
1462
1463 /**
1464 * ���O�_�C�A���O���J��
1465 * @param[in,out] info.filename �t�@�C���������l
1466 * OK���A�t�@�C�����A�s�v����������free()��������
1467 * @retval TRUE [ok] ����������
1468 * @retval FALSE �L�����Z��������
1469 */
1470 BOOL FLogOpenDialog(HINSTANCE hInst, HWND hWnd, FLogDlgInfo_t *info)
1471 {
1472 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 INT_PTR ret = TTDialogBoxParam(
1482 hInst, MAKEINTRESOURCE(IDD_LOGDLG),
1483 hWnd, LogFnHook, (LPARAM)work);
1484 free(srcfnameW);
1485 free(work);
1486 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 char *FLogGetLogFilename(const char *log_filename)
1503 {
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
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