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 8852 - (show annotations) (download) (as text)
Mon Jul 13 15:31:46 2020 UTC (3 years, 8 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/filesys.cpp
File MIME type: text/x-c++src
File size: 56911 byte(s)
ログファイルダイアログを追加

- ログダイアログ(IDD_LOGDLG)を追加
  - ログファイルのダイアログ表示に共通関数を使用しないよう修正
    - GetTransFname()#ttpfile を使用しない
  - filesys_log.rc, filesys_log_res.h 追加
  - ログコメントダイアログ(IDD_COMMENT_DIALOG)を移動
  - VS2005,2019,cmake にファイルを追加
- LogVar#filesys.cpp をグローバル変数からファイル内変数に変更
  - APIを追加,Log...()#filesys.cpp
1 /*
2 * Copyright (C) 1994-1998 T. Teranishi
3 * (C) 2005-2020 TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 /* TERATERM.EXE, file transfer routines */
31 #include <stdio.h>
32 #include <io.h>
33 #include <process.h>
34 #include <windows.h>
35 #include <htmlhelp.h>
36 #include <assert.h>
37
38 #include "teraterm.h"
39 #include "tttypes.h"
40 #include "ttftypes.h"
41 #include "ftdlg.h"
42 #include "protodlg.h"
43 #include "ttwinman.h"
44 #include "commlib.h"
45 #include "ttcommon.h"
46 #include "ttdde.h"
47 #include "ttlib.h"
48 #include "dlglib.h"
49 #include "vtterm.h"
50 #include "win16api.h"
51 #include "ftlib.h"
52 #include "buffer.h"
53 #include "helpid.h"
54 #include "layer_for_unicode.h"
55
56 #include "filesys.h"
57 #include "tt_res.h"
58 #include "filesys_log_res.h"
59
60 #define FS_BRACKET_NONE 0
61 #define FS_BRACKET_START 1
62 #define FS_BRACKET_END 2
63
64 static PFileVar LogVar = NULL;
65 PFileVar SendVar = NULL;
66 PFileVar FileVar = NULL;
67 static PCHAR ProtoVar = NULL;
68 static int ProtoId;
69
70 BOOL FileLog = FALSE;
71 BOOL BinLog = FALSE;
72 BOOL DDELog = FALSE;
73 static BOOL FileRetrySend, FileRetryEcho, FileCRSend, FileReadEOF, BinaryMode;
74 static BYTE FileByte;
75
76 #define FILE_SEND_BUF_SIZE 8192
77 struct FileSendHandler {
78 CHAR buf[FILE_SEND_BUF_SIZE];
79 int pos;
80 int end;
81 };
82 static struct FileSendHandler FileSendHandler;
83 static int FileDlgRefresh;
84
85 static int FileBracketMode = FS_BRACKET_NONE;
86 static int FileBracketPtr = 0;
87 static char BracketStartStr[] = "\033[200~";
88 static char BracketEndStr[] = "\033[201~";
89
90 static BOOL FSend = FALSE;
91
92 HWND HWndLog = NULL; //steven add
93
94 static HMODULE HTTFILE = NULL;
95 static int TTFILECount = 0;
96
97 PGetSetupFname GetSetupFname;
98 static PGetTransFname GetTransFname;
99 PGetMultiFname GetMultiFname;
100 PGetGetFname GetGetFname;
101 PSetFileVar SetFileVar;
102 PGetXFname GetXFname;
103 PProtoInit ProtoInit;
104 PProtoParse ProtoParse;
105 PProtoTimeOutProc ProtoTimeOutProc;
106 PProtoCancel ProtoCancel;
107 PTTFILESetUILanguageFile TTFILESetUILanguageFile;
108 PTTFILESetFileSendFilter TTFILESetFileSendFilter;
109
110 #define IdGetSetupFname 1
111 #define IdGetTransFname 2
112 #define IdGetMultiFname 3
113 #define IdGetGetFname 4
114 #define IdSetFileVar 5
115 #define IdGetXFname 6
116
117 #define IdProtoInit 7
118 #define IdProtoParse 8
119 #define IdProtoTimeOutProc 9
120 #define IdProtoCancel 10
121
122 #define IdTTFILESetUILanguageFile 11
123 #define IdTTFILESetFileSendFilter 12
124
125 /*
126 Line Head flag for timestamping
127 2007.05.24 Gentaro
128 */
129 enum enumLineEnd {
130 Line_Other = 0,
131 Line_LineHead = 1,
132 Line_FileHead = 2,
133 };
134
135 enum enumLineEnd eLineEnd = Line_LineHead;
136
137
138 // �x�����������p�X���b�h�����b�Z�[�W
139 #define WM_DPC_LOGTHREAD_SEND (WM_APP + 1)
140
141 static void CloseFileSync(PFileVar ptr);
142
143
144 BOOL LoadTTFILE()
145 {
146 BOOL Err;
147
148 if (HTTFILE != NULL)
149 {
150 TTFILECount++;
151 return TRUE;
152 }
153 else
154 TTFILECount = 0;
155
156 HTTFILE = LoadHomeDLL("TTPFILE.DLL");
157 if (HTTFILE == NULL)
158 return FALSE;
159
160 Err = FALSE;
161
162 GetSetupFname = (PGetSetupFname)GetProcAddress(HTTFILE,
163 MAKEINTRESOURCE(IdGetSetupFname));
164 if (GetSetupFname==NULL)
165 Err = TRUE;
166
167 GetTransFname = (PGetTransFname)GetProcAddress(HTTFILE,
168 MAKEINTRESOURCE(IdGetTransFname));
169 if (GetTransFname==NULL)
170 Err = TRUE;
171
172 GetMultiFname = (PGetMultiFname)GetProcAddress(HTTFILE,
173 MAKEINTRESOURCE(IdGetMultiFname));
174 if (GetMultiFname==NULL)
175 Err = TRUE;
176
177 GetGetFname = (PGetGetFname)GetProcAddress(HTTFILE,
178 MAKEINTRESOURCE(IdGetGetFname));
179 if (GetGetFname==NULL)
180 Err = TRUE;
181
182 SetFileVar = (PSetFileVar)GetProcAddress(HTTFILE,
183 MAKEINTRESOURCE(IdSetFileVar));
184 if (SetFileVar==NULL)
185 Err = TRUE;
186
187 GetXFname = (PGetXFname)GetProcAddress(HTTFILE,
188 MAKEINTRESOURCE(IdGetXFname));
189 if (GetXFname==NULL)
190 Err = TRUE;
191
192 ProtoInit = (PProtoInit)GetProcAddress(HTTFILE,
193 MAKEINTRESOURCE(IdProtoInit));
194 if (ProtoInit==NULL)
195 Err = TRUE;
196
197 ProtoParse = (PProtoParse)GetProcAddress(HTTFILE,
198 MAKEINTRESOURCE(IdProtoParse));
199 if (ProtoParse==NULL)
200 Err = TRUE;
201
202 ProtoTimeOutProc = (PProtoTimeOutProc)GetProcAddress(HTTFILE,
203 MAKEINTRESOURCE(IdProtoTimeOutProc));
204 if (ProtoTimeOutProc==NULL)
205 Err = TRUE;
206
207 ProtoCancel = (PProtoCancel)GetProcAddress(HTTFILE,
208 MAKEINTRESOURCE(IdProtoCancel));
209 if (ProtoCancel==NULL)
210 Err = TRUE;
211
212 TTFILESetUILanguageFile = (PTTFILESetUILanguageFile)GetProcAddress(HTTFILE,
213 MAKEINTRESOURCE(IdTTFILESetUILanguageFile));
214 if (TTFILESetUILanguageFile==NULL) {
215 Err = TRUE;
216 }
217 else {
218 TTFILESetUILanguageFile(ts.UILanguageFile);
219 }
220
221 TTFILESetFileSendFilter = (PTTFILESetFileSendFilter)GetProcAddress(HTTFILE,
222 MAKEINTRESOURCE(IdTTFILESetFileSendFilter));
223 if (TTFILESetFileSendFilter==NULL) {
224 Err = TRUE;
225 }
226 else {
227 TTFILESetFileSendFilter(ts.FileSendFilter);
228 }
229
230 if (Err)
231 {
232 FreeLibrary(HTTFILE);
233 HTTFILE = NULL;
234 return FALSE;
235 }
236 else {
237 TTFILECount = 1;
238 return TRUE;
239 }
240 }
241
242 BOOL FreeTTFILE()
243 {
244 if (TTFILECount==0)
245 return FALSE;
246 TTFILECount--;
247 if (TTFILECount>0)
248 return TRUE;
249 if (HTTFILE!=NULL)
250 {
251 FreeLibrary(HTTFILE);
252 HTTFILE = NULL;
253 }
254 return TRUE;
255 }
256
257 static PFileTransDlg FLogDlg = NULL;
258 static PFileTransDlg SendDlg = NULL;
259 static PProtoDlg PtDlg = NULL;
260
261 static BOOL OpenFTDlg(PFileVar fv)
262 {
263 PFileTransDlg FTDlg;
264
265 FTDlg = new CFileTransDlg();
266
267 fv->StartTime = 0;
268 fv->ProgStat = 0;
269
270 if (fv->OpId != OpLog) {
271 fv->HideDialog = ts.FTHideDialog;
272 }
273
274 if (FTDlg!=NULL)
275 {
276 FTDlg->Create(hInst, HVTWin, fv, &cv, &ts);
277 FTDlg->RefreshNum();
278 if (fv->OpId == OpLog) {
279 HWndLog = FTDlg->m_hWnd; // steven add
280 }
281 }
282
283 if (fv->OpId==OpLog)
284 FLogDlg = FTDlg; /* Log */
285 else
286 SendDlg = FTDlg; /* File send */
287
288 fv->StartTime = GetTickCount();
289 if (fv->OpId == OpSendFile) {
290 HWND HFTDlg = FTDlg->GetSafeHwnd();
291 InitDlgProgress(HFTDlg, IDC_TRANSPROGRESS, &fv->ProgStat);
292 ShowWindow(GetDlgItem(HFTDlg, IDC_TRANS_ELAPSED), SW_SHOW);
293 }
294
295 return (FTDlg!=NULL);
296 }
297
298 void ShowFTDlg(WORD OpId)
299 {
300 if (OpId == OpLog) {
301 if (FLogDlg != NULL) {
302 FLogDlg->ShowWindow(SW_SHOWNORMAL);
303 SetForegroundWindow(FLogDlg->GetSafeHwnd());
304 }
305 }
306 else {
307 if (SendDlg != NULL) {
308 SendDlg->ShowWindow(SW_SHOWNORMAL);
309 SetForegroundWindow(SendDlg->GetSafeHwnd());
310 }
311 }
312 }
313
314 BOOL NewFileVar(PFileVar *fv)
315 {
316 if ((*fv)==NULL)
317 {
318 *fv = (PFileVar)malloc(sizeof(TFileVar));
319 if ((*fv)!=NULL)
320 {
321 char FileDirExpanded[MAX_PATH];
322 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
323 memset(*fv, 0, sizeof(TFileVar));
324 strncpy_s((*fv)->FullName, sizeof((*fv)->FullName), FileDirExpanded, _TRUNCATE);
325 AppendSlash((*fv)->FullName,sizeof((*fv)->FullName));
326 (*fv)->DirLen = strlen((*fv)->FullName);
327 (*fv)->FileOpen = FALSE;
328 (*fv)->OverWrite = ((ts.FTFlag & FT_RENAME) == 0);
329 (*fv)->HMainWin = HVTWin;
330 (*fv)->Success = FALSE;
331 (*fv)->NoMsg = FALSE;
332 (*fv)->HideDialog = FALSE;
333 }
334 }
335
336 return ((*fv)!=NULL);
337 }
338
339 void FreeFileVar(PFileVar *fv)
340 {
341 if ((*fv)!=NULL)
342 {
343 CloseFileSync(*fv);
344 //if ((*fv)->FileOpen) _lclose((*fv)->FileHandle);
345 if ((*fv)->FnStrMemHandle != 0)
346 {
347 GlobalUnlock((*fv)->FnStrMemHandle);
348 GlobalFree((*fv)->FnStrMemHandle);
349 }
350 free(*fv);
351 *fv = NULL;
352 }
353 }
354
355 /**
356 * �t�@�C�������������u������
357 * &h �z�X�g�����u�� (2007.5.14)
358 * &p TCP�|�[�g�������u�� (2009.6.12)
359 * &u ���O�I���������[�U��
360 */
361 static void ConvertLogname(char *c, int destlen)
362 {
363 char buf[MAXPATHLEN], buf2[MAXPATHLEN], *p = c;
364 char tmphost[1024];
365 char tmpuser[256+1];
366 DWORD len_user = sizeof(tmpuser);
367
368 memset(buf, 0, sizeof(buf));
369
370 while(*p != '\0') {
371 if (*p == '&' && *(p+1) != '\0') {
372 switch (*(p+1)) {
373 case 'h':
374 if (cv.Open) {
375 if (cv.PortType == IdTCPIP) {
376 // �z�X�g����IPv6�A�h���X�����A�t�@�C�������g�p�����������������������A
377 // �]�v�����������������B
378 // (2013.3.9 yutaka)
379 strncpy_s(tmphost, sizeof(tmphost), ts.HostName, _TRUNCATE);
380 //strncpy_s(tmphost, sizeof(tmphost), "2001:0db8:bd05:01d2:288a:1fc0:0001:10ee", _TRUNCATE);
381 replaceInvalidFileNameChar(tmphost, '_');
382 strncat_s(buf,sizeof(buf), tmphost, _TRUNCATE);
383 }
384 else if (cv.PortType == IdSerial) {
385 strncpy_s(buf2,sizeof(buf2),buf,_TRUNCATE);
386 _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%sCOM%d", buf2, ts.ComPort);
387 }
388 }
389 break;
390 case 'p':
391 if (cv.Open) {
392 if (cv.PortType == IdTCPIP) {
393 char port[6];
394 _snprintf_s(port, sizeof(port), _TRUNCATE, "%d", ts.TCPPort);
395 strncat_s(buf,sizeof(buf),port,_TRUNCATE);
396 }
397 }
398 break;
399 case 'u':
400 if (GetUserName(tmpuser, &len_user) != 0) {
401 strncat_s(buf,sizeof(buf),tmpuser,_TRUNCATE);
402 }
403 break;
404 default:
405 strncpy_s(buf2,sizeof(buf2),p,2);
406 strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
407 }
408 p++;
409 }
410 else {
411 strncpy_s(buf2,sizeof(buf2),p,1);
412 strncat_s(buf,sizeof(buf),buf2,_TRUNCATE);
413 }
414 p++;
415 }
416 strncpy_s(c, destlen, buf, _TRUNCATE);
417 }
418
419 static void FixLogOption()
420 {
421 if (ts.LogBinary) {
422 ts.LogTypePlainText = false;
423 ts.LogTimestamp = false;
424 }
425 }
426
427
428 // �X���b�h���I�����t�@�C�����N���[�Y
429 static void CloseFileSync(PFileVar ptr)
430 {
431 BOOL ret;
432
433 if (!ptr->FileOpen)
434 return;
435
436 if (ptr->LogThread != INVALID_HANDLE_VALUE) {
437 // �X���b�h���I������
438 ret = PostThreadMessage(ptr->LogThreadId, WM_QUIT, 0, 0);
439 if (ret != 0) {
440 // �X���b�h�L���[���G���L���[���������������������������s���B
441 WaitForSingleObject(ptr->LogThread, INFINITE);
442 }
443 else {
444 //DWORD code = GetLastError();
445 }
446 CloseHandle(ptr->LogThread);
447 ptr->LogThread = INVALID_HANDLE_VALUE;
448 }
449 CloseHandle(ptr->FileHandle);
450 }
451
452 // �x�����������p�X���b�h
453 static unsigned _stdcall DeferredLogWriteThread(void *arg)
454 {
455 MSG msg;
456 PFileVar fv = (PFileVar)arg;
457 PCHAR buf;
458 DWORD buflen;
459 DWORD wrote;
460
461 PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
462
463 // �X���b�h�L���[���������I�������������X���b�h�����������m�����B
464 if (fv->LogThreadEvent != NULL) {
465 SetEvent(fv->LogThreadEvent);
466 }
467
468 while (GetMessage(&msg, NULL, 0, 0) > 0) {
469 switch (msg.message) {
470 case WM_DPC_LOGTHREAD_SEND:
471 buf = (PCHAR)msg.wParam;
472 buflen = (DWORD)msg.lParam;
473 WriteFile(LogVar->FileHandle, buf, buflen, &wrote, NULL);
474 free(buf); // ����������������
475 break;
476
477 case WM_QUIT:
478 goto end;
479 break;
480 }
481 }
482
483 end:
484 _endthreadex(0);
485 return (0);
486 }
487
488 /**
489 * �_�C�A���O�����e�� ts ����������
490 *
491 * TODO
492 * �_�C�A���O�����������l�������I��������
493 * ����������������������������������������������?
494 */
495 static void SetLogFlags(HWND Dialog)
496 {
497 WORD BinFlag, val;
498
499 GetRB(Dialog, &BinFlag, IDC_FOPTBIN, IDC_FOPTBIN);
500 ts.LogBinary = BinFlag;
501
502 GetRB(Dialog, &val, IDC_FOPTAPPEND, IDC_FOPTAPPEND);
503 ts.Append = val;
504
505 if (!BinFlag) {
506 GetRB(Dialog, &val, IDC_PLAINTEXT, IDC_PLAINTEXT);
507 ts.LogTypePlainText = val;
508
509 GetRB(Dialog, &val, IDC_TIMESTAMP, IDC_TIMESTAMP);
510 ts.LogTimestamp = val;
511 }
512
513 GetRB(Dialog, &val, IDC_HIDEDIALOG, IDC_HIDEDIALOG);
514 ts.LogHideDialog = val;
515
516 GetRB(Dialog, &val, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST);
517 ts.LogAllBuffIncludedInFirst = val;
518
519 ts.LogTimestampType = (GetCurSel(Dialog, IDC_TIMESTAMPTYPE) - 1);
520 }
521
522 /**
523 * ���O�t�@�C���`�F�b�N
524 *
525 * @param[in] filename
526 * @param[out] exist TURE/FALSE
527 * @param[out] bom 0 no BOM (or file not exist)
528 * 1 UTF-8
529 * 2 UTF-16LE
530 * 3 UTF-16BE
531 */
532 static void CheckLogFile(const char *filename, BOOL *exist, int *bom)
533 {
534 // �t�@�C������������?
535 DWORD logdir = GetFileAttributes(filename);
536 if ((logdir != INVALID_FILE_ATTRIBUTES) && ((logdir & FILE_ATTRIBUTE_DIRECTORY) == 0)) {
537 // �t�@�C���������� , �A�y���h����������
538 *exist = TRUE;
539
540 // BOM�L��/�����`�F�b�N
541 FILE *fp = fopen(filename, "rb");
542 unsigned char tmp[4];
543 size_t l = fread(tmp, 1, sizeof(tmp), fp);
544 fclose(fp);
545 if (l < 2) {
546 *bom = 0;
547 } else if (l >= 2 && tmp[0] == 0xff && tmp[1] == 0xfe) {
548 // UTF-16LE
549 *bom = 2;
550 } else if (l >= 2 && tmp[0] == 0xfe && tmp[1] == 0xff) {
551 // UTF-16BE
552 *bom = 3;
553 } else if (l >= 3 && tmp[0] == 0xef && tmp[1] == 0xbb && tmp[2] == 0xbf) {
554 // UTF-8
555 *bom = 1;
556 } else {
557 *bom = 0;
558 }
559 }
560 else {
561 // �t�@�C���������A�V�K
562 *exist = FALSE;
563 *bom = 0;
564 }
565 }
566
567 static void CheckLogFile(HWND Dialog, const char *filename)
568 {
569 BOOL exist;
570 int bom;
571 CheckLogFile(filename, &exist, &bom);
572 if (exist) {
573 // �t�@�C������������ -> �A�y���h����������?
574 CheckDlgButton(Dialog, IDC_FOPTAPPEND, BST_CHECKED);
575 if (bom != 0) {
576 // BOM�L��
577 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
578 }
579 else {
580 // BOM����
581 CheckDlgButton(Dialog, IDC_BOM, BST_UNCHECKED);
582 }
583 }
584 else {
585 // �t�@�C���������A�V�K
586 CheckDlgButton(Dialog, IDC_FOPTAPPEND, BST_UNCHECKED);
587 CheckDlgButton(Dialog, IDC_BOM, BST_CHECKED);
588 }
589 }
590
591 typedef struct {
592 char *filename;
593 BOOL append;
594 BOOL bom;
595 } LogDlgData_t;
596
597 static INT_PTR CALLBACK LogFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam)
598 {
599 static const DlgTextInfo TextInfos[] = {
600 { 0, "DLG_TABSHEET_TITLE_LOG" },
601 { IDC_FOPTBIN, "DLG_FOPT_BINARY" },
602 { IDC_FOPTAPPEND, "DLG_FOPT_APPEND" },
603 { IDC_PLAINTEXT, "DLG_FOPT_PLAIN" },
604 { IDC_HIDEDIALOG, "DLG_FOPT_HIDEDIALOG" },
605 { IDC_ALLBUFF_INFIRST, "DLG_FOPT_ALLBUFFINFIRST" },
606 { IDC_TIMESTAMP, "DLG_FOPT_TIMESTAMP" },
607 };
608 static const I18nTextInfo timestamp_list[] = {
609 { "DLG_FOPT_TIMESTAMP_LOCAL", L"Local Time" },
610 { "DLG_FOPT_TIMESTAMP_UTC", L"UTC" },
611 { "DLG_FOPT_TIMESTAMP_ELAPSED_LOGGING", L"Elapsed Time (Logging)" },
612 { "DLG_FOPT_TIMESTAMP_ELAPSED_CONNECTION", L"Elapsed Time (Connection)" },
613 };
614 const char *UILanguageFile = ts.UILanguageFile;
615 LogDlgData_t *data = (LogDlgData_t *)GetWindowLongPtr(Dialog, DWLP_USER);
616
617 if (Message == RegisterWindowMessage(HELPMSGSTRING)) {
618 // �R�����_�C�A���O�������w���v���b�Z�[�W���t��������
619 Message = WM_COMMAND;
620 wParam = IDHELP;
621 }
622 switch (Message) {
623 case WM_INITDIALOG: {
624 data = (LogDlgData_t *)lParam;
625 SetWindowLongPtr(Dialog, DWLP_USER, (LONG_PTR)data);
626 ::DragAcceptFiles(Dialog, TRUE);
627
628 SetDlgTexts(Dialog, TextInfos, _countof(TextInfos), UILanguageFile);
629 SetI18nList("Tera Term", Dialog, IDC_TIMESTAMPTYPE, timestamp_list, _countof(timestamp_list),
630 UILanguageFile, 0);
631
632 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_ADDSTRING, 0, (LPARAM)"UTF-8");
633 SendDlgItemMessage(Dialog, IDC_TEXTCODING_DROPDOWN, CB_SETCURSEL, 0, 0);
634
635 SetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, data->filename);
636 free(data->filename);
637 data->filename = NULL;
638
639 // Binary/Text �`�F�b�N�{�b�N�X
640 if (ts.LogBinary) {
641 SendDlgItemMessage(Dialog, IDC_FOPTBIN, BM_SETCHECK, BST_CHECKED, 0);
642 }
643 else {
644 SendDlgItemMessage(Dialog, IDC_FOPTTEXT, BM_SETCHECK, BST_CHECKED, 0);
645 }
646
647 // Append �`�F�b�N�{�b�N�X
648 if (ts.Append) {
649 SetRB(Dialog, 1, IDC_FOPTAPPEND, IDC_FOPTAPPEND);
650 }
651
652 // Plain Text �`�F�b�N�{�b�N�X
653 if (ts.LogBinary) {
654 // Binary�t���O���L�����������`�F�b�N��������
655 DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_PLAINTEXT);
656 }
657 else if (ts.LogTypePlainText) {
658 SetRB(Dialog, 1, IDC_PLAINTEXT, IDC_PLAINTEXT);
659 }
660
661 // Hide dialog�`�F�b�N�{�b�N�X (2008.1.30 maya)
662 if (ts.LogHideDialog) {
663 SetRB(Dialog, 1, IDC_HIDEDIALOG, IDC_HIDEDIALOG);
664 }
665
666 // Include screen buffer�`�F�b�N�{�b�N�X (2013.9.29 yutaka)
667 if (ts.LogAllBuffIncludedInFirst) {
668 SetRB(Dialog, 1, IDC_ALLBUFF_INFIRST, IDC_ALLBUFF_INFIRST);
669 }
670
671 // timestamp�`�F�b�N�{�b�N�X (2006.7.23 maya)
672 if (ts.LogBinary) {
673 // Binary�t���O���L�����������`�F�b�N��������
674 DisableDlgItem(Dialog, IDC_TIMESTAMP, IDC_TIMESTAMP);
675 }
676 else if (ts.LogTimestamp) {
677 SetRB(Dialog, 1, IDC_TIMESTAMP, IDC_TIMESTAMP);
678 }
679
680 // timestamp ����
681 int tstype = ts.LogTimestampType == TIMESTAMP_LOCAL ? 0 :
682 ts.LogTimestampType == TIMESTAMP_UTC ? 1 :
683 ts.LogTimestampType == TIMESTAMP_ELAPSED_LOGSTART ? 2 :
684 ts.LogTimestampType == TIMESTAMP_ELAPSED_CONNECTED ? 3 : 0;
685 SendDlgItemMessage(Dialog, IDC_TIMESTAMPTYPE, CB_SETCURSEL, tstype, 0);
686 if (ts.LogBinary || !ts.LogTimestamp) {
687 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
688 }
689
690 CenterWindow(Dialog, GetParent(Dialog));
691
692 return TRUE;
693 }
694
695 case WM_COMMAND:
696 switch (LOWORD(wParam)) {
697 case IDOK: {
698 char filename[MAX_PATH];
699 GetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
700 data->filename = _strdup(filename);
701 data->append = IsDlgButtonChecked(Dialog, IDC_FOPTAPPEND) == BST_CHECKED;
702 data->bom = IsDlgButtonChecked(Dialog, IDC_BOM) == BST_CHECKED;
703 SetLogFlags(Dialog);
704 EndDialog(Dialog, IDOK);
705 break;
706 }
707 case IDCANCEL:
708 EndDialog(Dialog, IDCANCEL);
709 break;
710 case IDHELP:
711 OpenHelp(HH_HELP_CONTEXT, HlpFileLog, ts.UILanguageFile);
712 break;
713 case IDC_FOPT_FILENAME_BUTTON: {
714 /* save current dir */
715 wchar_t curdir[MAXPATHLEN];
716 _GetCurrentDirectoryW(_countof(curdir), curdir);
717
718 char fname[MAX_PATH];
719 GetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, fname, _countof(fname));
720
721 char FNFilter[128*3];
722 get_lang_msg("FILEDLG_ALL_FILTER", FNFilter, sizeof(FNFilter), "All(*.*)\\0*.*\\0\\0", UILanguageFile);
723
724 char caption[MAX_PATH];
725 char uimsg[MAX_UIMSG];
726 get_lang_msg("FILEDLG_TRANS_TITLE_LOG", uimsg, sizeof(uimsg), TitLog, UILanguageFile);
727 strncpy_s(caption, sizeof(caption),"Tera Term: ", _TRUNCATE);
728 strncat_s(caption, sizeof(caption), uimsg, _TRUNCATE);
729
730 OPENFILENAME ofn = {};
731 ofn.lStructSize = get_OPENFILENAME_SIZEA();
732 //ofn.Flags = OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT;
733 ofn.Flags |= OFN_EXPLORER | OFN_ENABLESIZING;
734 ofn.Flags |= OFN_SHOWHELP;
735 ofn.Flags |= OFN_NOCHANGEDIR; // ��������������������������������
736 ofn.hwndOwner = Dialog;
737 ofn.lpstrFilter = FNFilter;
738 ofn.nFilterIndex = 1;
739 ofn.lpstrFile = fname;
740 ofn.nMaxFile = sizeof(fname);
741 ofn.lpstrTitle = caption;
742 BOOL Ok = GetSaveFileName(&ofn);
743 if (Ok) {
744 SetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, fname);
745 }
746
747 /* restore dir */
748 _SetCurrentDirectoryW(curdir);
749
750 break;
751 }
752 case IDC_FOPTBIN:
753 DisableDlgItem(Dialog, IDC_PLAINTEXT, IDC_TIMESTAMP);
754 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
755 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), FALSE);
756 break;
757 case IDC_FOPTTEXT:
758 EnableWindow(GetDlgItem(Dialog, IDC_TEXTCODING_DROPDOWN), TRUE);
759 EnableDlgItem(Dialog, IDC_PLAINTEXT, IDC_TIMESTAMP);
760 // FALLTHROUGH -- BinFlag �� off ������ Timestamp �������L��/��������������
761 case IDC_TIMESTAMP:
762 if (IsDlgButtonChecked(Dialog, IDC_TIMESTAMP) == BST_CHECKED) {
763 EnableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
764 }
765 else {
766 DisableDlgItem(Dialog, IDC_TIMESTAMPTYPE, IDC_TIMESTAMPTYPE);
767 }
768 break;
769 case IDC_FOPT_FILENAME_EDIT:
770 if (HIWORD(wParam) == EN_CHANGE){
771 char filename[MAX_PATH];
772 GetDlgItemTextA(Dialog, IDC_FOPT_FILENAME_EDIT, filename, _countof(filename));
773 CheckLogFile(Dialog, filename);
774 }
775 break;
776 }
777 break;
778 case WM_DROPFILES: {
779 // �����h���b�v��������������1������������
780 HDROP hDrop = (HDROP)wParam;
781 const UINT len = _DragQueryFileW(hDrop, 0, NULL, 0);
782 if (len == 0) {
783 DragFinish(hDrop);
784 return TRUE;
785 }
786 wchar_t *filename = (wchar_t *)malloc(sizeof(wchar_t) * (len + 1));
787 _DragQueryFileW(hDrop, 0, filename, len + 1);
788 filename[len] = '\0';
789 _SetDlgItemTextW(Dialog, IDC_FOPT_FILENAME_EDIT, filename);
790 SendDlgItemMessage(Dialog, IDC_FOPT_FILENAME_EDIT, EM_SETSEL, len, len);
791 free(filename);
792 DragFinish(hDrop);
793 return TRUE;
794 }
795 }
796 return FALSE;
797 }
798
799 static BOOL LogStart()
800 {
801 unsigned tid;
802
803 if ((FileLog) || (BinLog)) return FALSE;
804
805 assert(LogVar != NULL);
806
807 if (strlen(&(LogVar->FullName[LogVar->DirLen]))==0) {
808 // �t�@�C����������������������
809 return FALSE;
810 }
811
812 if (! LoadTTFILE()) return FALSE;
813
814 LogVar->OpId = OpLog;
815 (*SetFileVar)(LogVar);
816 FixLogOption();
817
818 if (ts.LogBinary > 0)
819 {
820 BinLog = TRUE;
821 FileLog = FALSE;
822 if (! CreateBinBuf())
823 {
824 FileTransEnd(OpLog);
825 return FALSE;
826 }
827 }
828 else {
829 BinLog = FALSE;
830 FileLog = TRUE;
831 if (! CreateLogBuf())
832 {
833 FileTransEnd(OpLog);
834 return FALSE;
835 }
836 }
837 cv.LStart = cv.LogPtr;
838 cv.LCount = 0;
839 if (ts.LogHideDialog)
840 LogVar->HideDialog = 1;
841
842 /* 2007.05.24 Gentaro */
843 eLineEnd = Line_LineHead;
844
845 if (ts.Append > 0)
846 {
847 int dwShareMode = FILE_SHARE_READ;
848 if (!ts.LogLockExclusive) {
849 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
850 }
851 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
852 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
853 if (LogVar->FileHandle != INVALID_HANDLE_VALUE){
854 SetFilePointer(LogVar->FileHandle, 0, NULL, FILE_END);
855 /* 2007.05.24 Gentaro
856 If log file already exists,
857 a newline is inserted before the first timestamp.
858 */
859 eLineEnd = Line_FileHead;
860 }
861 }
862 else {
863 int dwShareMode = FILE_SHARE_READ;
864 if (!ts.LogLockExclusive) {
865 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
866 }
867 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
868 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
869 }
870 LogVar->FileOpen = (LogVar->FileHandle != INVALID_HANDLE_VALUE);
871 if (! LogVar->FileOpen)
872 {
873 char msg[128];
874
875 // �t�@�C���I�[�v���G���[�������b�Z�[�W�\�������������B(2008.7.9 yutaka)
876 if (LogVar->NoMsg == FALSE) {
877 _snprintf_s(msg, sizeof(msg), _TRUNCATE, "Can not create a `%s' file. (%d)", LogVar->FullName, GetLastError());
878 MessageBox(NULL, msg, "Tera Term: File open error", MB_OK | MB_ICONERROR);
879 }
880
881 FileTransEnd(OpLog);
882 return FALSE;
883 }
884 LogVar->ByteCount = 0;
885
886 // Log rotate configuration
887 LogVar->RotateMode = ts.LogRotate;
888 LogVar->RotateSize = ts.LogRotateSize;
889 LogVar->RotateStep = ts.LogRotateStep;
890
891 // Log rotate���L���������A�����t�@�C���T�C�Y�����������B
892 // �������t�@�C�������������T�C�Y�����[�e�[�g�������������C���B
893 // (2016.4.9 yutaka)
894 if (LogVar->RotateMode != ROTATE_NONE) {
895 DWORD size = GetFileSize(LogVar->FileHandle, NULL);
896 if (size != -1)
897 LogVar->ByteCount = size;
898 }
899
900 if (! OpenFTDlg(LogVar)) {
901 FileTransEnd(OpLog);
902 return FALSE;
903 }
904
905 // �x�����������p�X���b�h���N�����B
906 // (2013.4.19 yutaka)
907 // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
908 // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
909 // �����������������C�������B
910 // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
911 // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
912 // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
913 // (2016.9.23 yutaka)
914 LogVar->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
915 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
916 LogVar->LogThreadId = tid;
917 if (LogVar->LogThreadEvent != NULL) {
918 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
919 CloseHandle(LogVar->LogThreadEvent);
920 }
921
922 // �����o�b�t�@�������f�[�^�������������o���������A
923 // ���O�������J�n�����B
924 // (2013.9.29 yutaka)
925 if (ts.LogAllBuffIncludedInFirst) {
926 DWORD ofs, size, written_size;
927 char buf[512];
928 const char *crlf = "\r\n";
929 DWORD crlf_len = 2;
930 for (ofs = 0 ; ; ofs++ ) {
931 // 1�����s�����������B���������������A�G�X�P�[�v�V�[�P���X�������������B
932 size = BuffGetAnyLineData(ofs, buf, sizeof(buf));
933 if (size == -1)
934 break;
935
936 #if 0
937 if (ts.DeferredLogWriteMode) { // �x����������
938 char *pbuf = (char *)malloc(size + 2);
939 memcpy(pbuf, buf, size);
940 pbuf[size] = '\r';
941 pbuf[size+1] = '\n';
942 Sleep(1); // �X���b�h�L���[�����������������A�R���e�L�X�g�X�C�b�`�������B
943 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)pbuf, size + 2);
944 } else { // �������B�l�b�g���[�N�o�R�����x���B
945 #endif
946 WriteFile(LogVar->FileHandle, buf, size, &written_size, NULL);
947 WriteFile(LogVar->FileHandle, crlf, crlf_len, &written_size, NULL);
948 #if 0
949 }
950 #endif
951 }
952 }
953
954 return TRUE;
955 }
956
957 void LogPut1(BYTE b)
958 {
959 cv.LogBuf[cv.LogPtr] = b;
960 cv.LogPtr++;
961 if (cv.LogPtr>=InBuffSize)
962 cv.LogPtr = cv.LogPtr-InBuffSize;
963
964 if (FileLog)
965 {
966 if (cv.LCount>=InBuffSize)
967 {
968 cv.LCount = InBuffSize;
969 cv.LStart = cv.LogPtr;
970 }
971 else
972 cv.LCount++;
973 }
974 else
975 cv.LCount = 0;
976
977 if (DDELog)
978 {
979 if (cv.DCount>=InBuffSize)
980 {
981 cv.DCount = InBuffSize;
982 cv.DStart = cv.LogPtr;
983 }
984 else
985 cv.DCount++;
986 }
987 else {
988 cv.DCount = 0;
989 // ���O���������}�N�����X�g�[���������������C���B
990 // ���O�����������x�}�N�����~�������A�o�b�t�@���C���f�b�N�X�������������������A
991 // ���x�}�N�������������������f�[�^�������������������B
992 // �}�N�������~���������������C���f�b�N�X�����������������������B
993 // (2006.12.26 yutaka)
994 cv.DStart = cv.LogPtr;
995 }
996 }
997
998 static BOOL Get1(PCHAR Buf, int *Start, int *Count, PBYTE b)
999 {
1000 if (*Count<=0) return FALSE;
1001 *b = Buf[*Start];
1002 (*Start)++;
1003 if (*Start>=InBuffSize)
1004 *Start = *Start-InBuffSize;
1005 (*Count)--;
1006 return TRUE;
1007 }
1008
1009
1010
1011 static CRITICAL_SECTION g_filelog_lock; /* ���b�N�p���� */
1012
1013 void logfile_lock_initialize(void)
1014 {
1015 InitializeCriticalSection(&g_filelog_lock);
1016 }
1017
1018 static inline void logfile_lock(void)
1019 {
1020 EnterCriticalSection(&g_filelog_lock);
1021 }
1022
1023 static inline void logfile_unlock(void)
1024 {
1025 LeaveCriticalSection(&g_filelog_lock);
1026 }
1027
1028 // �R�����g�����O����������
1029 static void CommentLogToFile(char *buf, int size)
1030 {
1031 DWORD wrote;
1032
1033 if (LogVar == NULL || !LogVar->FileOpen) {
1034 char uimsg[MAX_UIMSG];
1035 get_lang_msg("MSG_ERROR", uimsg, sizeof(uimsg), "ERROR", ts.UILanguageFile);
1036 get_lang_msg("MSG_COMMENT_LOG_OPEN_ERROR", ts.UIMsg, sizeof(ts.UIMsg),
1037 "It is not opened by the log file yet.", ts.UILanguageFile);
1038 ::MessageBox(NULL, ts.UIMsg, uimsg, MB_OK|MB_ICONEXCLAMATION);
1039 return;
1040 }
1041
1042 logfile_lock();
1043 WriteFile(LogVar->FileHandle, buf, size, &wrote, NULL);
1044 WriteFile(LogVar->FileHandle, "\r\n", 2, &wrote, NULL); // ���s
1045 /* Set Line End Flag
1046 2007.05.24 Gentaro
1047 */
1048 eLineEnd = Line_LineHead;
1049 logfile_unlock();
1050 }
1051
1052 // ���O�����[�e�[�g�����B
1053 // (2013.3.21 yutaka)
1054 static void LogRotate(void)
1055 {
1056 int loopmax = 10000; // XXX
1057 char filename[1024];
1058 char newfile[1024], oldfile[1024];
1059 int i, k;
1060 int dwShareMode = FILE_SHARE_READ;
1061 unsigned tid;
1062
1063 if (! LogVar->FileOpen) return;
1064
1065 if (LogVar->RotateMode == ROTATE_NONE)
1066 return;
1067
1068 if (LogVar->RotateMode == ROTATE_SIZE) {
1069 if (LogVar->ByteCount <= LogVar->RotateSize)
1070 return;
1071 //OutputDebugPrintf("%s: mode %d size %ld\n", __FUNCTION__, LogVar->RotateMode, LogVar->ByteCount);
1072 } else {
1073 return;
1074 }
1075
1076 logfile_lock();
1077 // ���O�T�C�Y���������������B
1078 LogVar->ByteCount = 0;
1079
1080 // �������������t�@�C�����N���[�Y�����A�������t�@�C�����I�[�v�������B
1081 CloseFileSync(LogVar);
1082 //_lclose(LogVar->FileHandle);
1083
1084 // �������[�e�[�V�������X�e�b�v�����w����������
1085 if (LogVar->RotateStep > 0)
1086 loopmax = LogVar->RotateStep;
1087
1088 for (i = 1 ; i <= loopmax ; i++) {
1089 _snprintf_s(filename, sizeof(filename), _TRUNCATE, "%s.%d", LogVar->FullName, i);
1090 if (_access_s(filename, 0) != 0)
1091 break;
1092 }
1093 if (i > loopmax) {
1094 // �������������������������A�������t�@�C�������p�������B
1095 i = loopmax;
1096 }
1097
1098 // ���t�@�C�������l�[���B
1099 for (k = i-1 ; k >= 0 ; k--) {
1100 if (k == 0)
1101 strncpy_s(oldfile, sizeof(oldfile), LogVar->FullName, _TRUNCATE);
1102 else
1103 _snprintf_s(oldfile, sizeof(oldfile), _TRUNCATE, "%s.%d", LogVar->FullName, k);
1104 _snprintf_s(newfile, sizeof(newfile), _TRUNCATE, "%s.%d", LogVar->FullName, k+1);
1105 remove(newfile);
1106 if (rename(oldfile, newfile) != 0) {
1107 OutputDebugPrintf("%s: rename %d\n", __FUNCTION__, errno);
1108 }
1109 }
1110
1111 // ���I�[�v��
1112 if (!ts.LogLockExclusive) {
1113 dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
1114 }
1115 LogVar->FileHandle = CreateFile(LogVar->FullName, GENERIC_WRITE, dwShareMode, NULL,
1116 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1117
1118 // �x�����������p�X���b�h���N�����B
1119 // (2013.4.19 yutaka)
1120 // DeferredLogWriteThread �X���b�h���N�������A�X���b�h�L���[�����������������O���A
1121 // ���O�t�@�C�����N���[�Y(CloseFileSync)���s���������A�G���L���[�����s���A�f�b�h���b�N
1122 // �����������������C�������B
1123 // �X���b�h�����������s�������A���O�����C�x���g�I�u�W�F�N�g���g�����A�X���b�h�L���[��
1124 // ���������������������������������B���O�t���C�x���g�I�u�W�F�N�g���g���������A
1125 // �V�X�e��(Windows OS)�������j�[�N�����O�������K�v�������B
1126 // (2016.9.26 yutaka)
1127 LogVar->LogThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1128 LogVar->LogThread = (HANDLE)_beginthreadex(NULL, 0, DeferredLogWriteThread, LogVar, 0, &tid);
1129 LogVar->LogThreadId = tid;
1130 if (LogVar->LogThreadEvent != NULL) {
1131 WaitForSingleObject(LogVar->LogThreadEvent, INFINITE);
1132 CloseHandle(LogVar->LogThreadEvent);
1133 }
1134
1135 logfile_unlock();
1136
1137 }
1138
1139 void LogToFile()
1140 {
1141 PCHAR Buf;
1142 int Start, Count;
1143 BYTE b;
1144 PCHAR WriteBuf;
1145 DWORD WriteBufMax, WriteBufLen;
1146 CHAR tmp[128];
1147 DWORD wrote;
1148
1149 if (! LogVar->FileOpen) return;
1150 if (FileLog)
1151 {
1152 Buf = cv.LogBuf;
1153 Start = cv.LStart;
1154 Count = cv.LCount;
1155 }
1156 else if (BinLog)
1157 {
1158 Buf = cv.BinBuf;
1159 Start = cv.BStart;
1160 Count = cv.BCount;
1161 }
1162 else
1163 return;
1164
1165 if (Buf==NULL) return;
1166 if (Count==0) return;
1167
1168 // ���b�N������(2004.8.6 yutaka)
1169 logfile_lock();
1170
1171 if (ts.DeferredLogWriteMode) {
1172 WriteBufMax = 8192;
1173 WriteBufLen = 0;
1174 WriteBuf = (PCHAR)malloc(WriteBufMax);
1175 while (Get1(Buf,&Start,&Count,&b)) {
1176 if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
1177 {
1178 tmp[0] = 0;
1179 if ( ts.LogTimestamp && eLineEnd ) {
1180 char *strtime = NULL;
1181
1182 switch (ts.LogTimestampType) {
1183 case TIMESTAMP_LOCAL:
1184 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1185 break;
1186 case TIMESTAMP_UTC:
1187 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1188 break;
1189 case TIMESTAMP_ELAPSED_LOGSTART:
1190 strtime = strelapsed(LogVar->StartTime);
1191 break;
1192 case TIMESTAMP_ELAPSED_CONNECTED:
1193 strtime = strelapsed(cv.ConnectedTime);
1194 break;
1195 }
1196
1197 /* 2007.05.24 Gentaro */
1198 if( eLineEnd == Line_FileHead ){
1199 strncat_s(tmp, sizeof(tmp), "\r\n", _TRUNCATE);
1200 }
1201 strncat_s(tmp, sizeof(tmp), "[", _TRUNCATE);
1202 strncat_s(tmp, sizeof(tmp), strtime, _TRUNCATE);
1203 strncat_s(tmp, sizeof(tmp), "] ", _TRUNCATE);
1204 }
1205
1206 /* 2007.05.24 Gentaro */
1207 if( b == 0x0a ){
1208 eLineEnd = Line_LineHead; /* set endmark*/
1209 }
1210 else {
1211 eLineEnd = Line_Other; /* clear endmark*/
1212 }
1213
1214 if (WriteBufLen >= (WriteBufMax*4/5)) {
1215 WriteBufMax *= 2;
1216 WriteBuf = (PCHAR)realloc(WriteBuf, WriteBufMax);
1217 }
1218 memcpy(&WriteBuf[WriteBufLen], tmp, strlen(tmp));
1219 WriteBufLen += strlen(tmp);
1220 WriteBuf[WriteBufLen++] = b;
1221
1222 (LogVar->ByteCount)++;
1223 }
1224 }
1225
1226 PostThreadMessage(LogVar->LogThreadId, WM_DPC_LOGTHREAD_SEND, (WPARAM)WriteBuf, WriteBufLen);
1227
1228 } else {
1229
1230 while (Get1(Buf,&Start,&Count,&b))
1231 {
1232 if (((cv.FilePause & OpLog)==0) && (! cv.ProtoFlag))
1233 {
1234 if ( ts.LogTimestamp && eLineEnd ) {
1235 char *strtime = NULL;
1236
1237 switch (ts.LogTimestampType) {
1238 case TIMESTAMP_LOCAL:
1239 strtime = mctimelocal(ts.LogTimestampFormat, FALSE);
1240 break;
1241 case TIMESTAMP_UTC:
1242 strtime = mctimelocal(ts.LogTimestampFormat, TRUE);
1243 break;
1244 case TIMESTAMP_ELAPSED_LOGSTART:
1245 strtime = strelapsed(LogVar->StartTime);
1246 break;
1247 case TIMESTAMP_ELAPSED_CONNECTED:
1248 strtime = strelapsed(cv.ConnectedTime);
1249 break;
1250 }
1251 WriteFile(LogVar->FileHandle, "[", 1, &wrote, NULL);
1252 WriteFile(LogVar->FileHandle, strtime, strlen(strtime), &wrote, NULL);
1253 WriteFile(LogVar->FileHandle, "] ", 2, &wrote, NULL);
1254 }
1255
1256 /* 2007.05.24 Gentaro */
1257 if( b == 0x0a ){
1258 eLineEnd = Line_LineHead; /* set endmark*/
1259 }
1260 else {
1261 eLineEnd = Line_Other; /* clear endmark*/
1262 }
1263
1264 WriteFile(LogVar->FileHandle, (PCHAR)&b, 1, &wrote, NULL);
1265 (LogVar->ByteCount)++;
1266 }
1267 }
1268
1269 }
1270
1271 logfile_unlock();
1272
1273 if (FileLog)
1274 {
1275 cv.LStart = Start;
1276 cv.LCount = Count;
1277 }
1278 else {
1279 cv.BStart = Start;
1280 cv.BCount = Count;
1281 }
1282 if (((cv.FilePause & OpLog) !=0) || cv.ProtoFlag) return;
1283 if (FLogDlg!=NULL)
1284 FLogDlg->RefreshNum();
1285
1286 // ���O�E���[�e�[�g
1287 LogRotate();
1288
1289 }
1290
1291 BOOL CreateLogBuf()
1292 {
1293 if (cv.HLogBuf==NULL)
1294 {
1295 cv.HLogBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1296 cv.LogBuf = NULL;
1297 cv.LogPtr = 0;
1298 cv.LStart = 0;
1299 cv.LCount = 0;
1300 cv.DStart = 0;
1301 cv.DCount = 0;
1302 }
1303 return (cv.HLogBuf!=NULL);
1304 }
1305
1306 void FreeLogBuf()
1307 {
1308 if ((cv.HLogBuf==NULL) || FileLog || DDELog)
1309 return;
1310 if (cv.LogBuf!=NULL)
1311 GlobalUnlock(cv.HLogBuf);
1312 GlobalFree(cv.HLogBuf);
1313 cv.HLogBuf = NULL;
1314 cv.LogBuf = NULL;
1315 cv.LogPtr = 0;
1316 cv.LStart = 0;
1317 cv.LCount = 0;
1318 cv.DStart = 0;
1319 cv.DCount = 0;
1320 }
1321
1322 BOOL CreateBinBuf()
1323 {
1324 if (cv.HBinBuf==NULL)
1325 {
1326 cv.HBinBuf = GlobalAlloc(GMEM_MOVEABLE,InBuffSize);
1327 cv.BinBuf = NULL;
1328 cv.BinPtr = 0;
1329 cv.BStart = 0;
1330 cv.BCount = 0;
1331 }
1332 return (cv.HBinBuf!=NULL);
1333 }
1334
1335 void FreeBinBuf()
1336 {
1337 if ((cv.HBinBuf==NULL) || BinLog)
1338 return;
1339 if (cv.BinBuf!=NULL)
1340 GlobalUnlock(cv.HBinBuf);
1341 GlobalFree(cv.HBinBuf);
1342 cv.HBinBuf = NULL;
1343 cv.BinBuf = NULL;
1344 cv.BinPtr = 0;
1345 cv.BStart = 0;
1346 cv.BCount = 0;
1347 }
1348
1349 void FileSendStart()
1350 {
1351 LONG Option = 0;
1352
1353 if (! cv.Ready || FSend) return;
1354 if (cv.ProtoFlag)
1355 {
1356 FreeFileVar(&SendVar);
1357 return;
1358 }
1359
1360 if (! LoadTTFILE())
1361 return;
1362 if (! NewFileVar(&SendVar))
1363 {
1364 FreeTTFILE();
1365 return;
1366 }
1367 SendVar->OpId = OpSendFile;
1368
1369 FSend = TRUE;
1370
1371 if (strlen(&(SendVar->FullName[SendVar->DirLen])) == 0) {
1372 char FileDirExpanded[MAX_PATH];
1373 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1374 if (ts.TransBin)
1375 Option |= LOGDLG_BINARY;
1376 SendVar->FullName[0] = 0;
1377 if (! (*GetTransFname)(SendVar, FileDirExpanded, GTF_SEND, &Option)) {
1378 FileTransEnd(OpSendFile);
1379 return;
1380 }
1381 ts.TransBin = CheckFlag(Option, LOGDLG_BINARY);
1382 }
1383 else
1384 (*SetFileVar)(SendVar);
1385
1386 SendVar->FileHandle = CreateFile(SendVar->FullName, GENERIC_READ, FILE_SHARE_READ, NULL,
1387 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1388 SendVar->FileOpen = (SendVar->FileHandle != INVALID_HANDLE_VALUE);
1389 if (! SendVar->FileOpen)
1390 {
1391 FileTransEnd(OpSendFile);
1392 return;
1393 }
1394 SendVar->ByteCount = 0;
1395 SendVar->FileSize = GetFSize(SendVar->FullName);
1396
1397 TalkStatus = IdTalkFile;
1398 FileRetrySend = FALSE;
1399 FileRetryEcho = FALSE;
1400 FileCRSend = FALSE;
1401 FileReadEOF = FALSE;
1402 FileSendHandler.pos = 0;
1403 FileSendHandler.end = 0;
1404 FileDlgRefresh = 0;
1405
1406 if (BracketedPasteMode()) {
1407 FileBracketMode = FS_BRACKET_START;
1408 FileBracketPtr = 0;
1409 BinaryMode = TRUE;
1410 }
1411 else {
1412 FileBracketMode = FS_BRACKET_NONE;
1413 BinaryMode = ts.TransBin;
1414 }
1415
1416 if (! OpenFTDlg(SendVar))
1417 FileTransEnd(OpSendFile);
1418 }
1419
1420 void FileTransEnd(WORD OpId)
1421 /* OpId = 0: close Log and FileSend
1422 OpLog: close Log
1423 OpSendFile: close FileSend */
1424 {
1425 if (((OpId==0) || (OpId==OpLog)) && (FileLog || BinLog))
1426 {
1427 FileLog = FALSE;
1428 BinLog = FALSE;
1429 if (FLogDlg!=NULL)
1430 {
1431 FLogDlg->DestroyWindow();
1432 FLogDlg = NULL;
1433 HWndLog = NULL; // steven add
1434 }
1435 FreeFileVar(&LogVar);
1436 FreeLogBuf();
1437 FreeBinBuf();
1438 FreeTTFILE();
1439 }
1440
1441 if (((OpId==0) || (OpId==OpSendFile)) && FSend)
1442 {
1443 FSend = FALSE;
1444 TalkStatus = IdTalkKeyb;
1445 if (SendDlg!=NULL)
1446 {
1447 SendDlg->DestroyWindow();
1448 SendDlg = NULL;
1449 }
1450 FreeFileVar(&SendVar);
1451 FreeTTFILE();
1452 }
1453
1454 EndDdeCmnd(0);
1455 }
1456
1457 int FSOut1(BYTE b)
1458 {
1459 if (BinaryMode)
1460 return CommBinaryOut(&cv,(PCHAR)&b,1);
1461 else if ((b>=0x20) || (b==0x09) || (b==0x0A) || (b==0x0D))
1462 return CommTextOut(&cv,(PCHAR)&b,1);
1463 else
1464 return 1;
1465 }
1466
1467 int FSEcho1(BYTE b)
1468 {
1469 if (BinaryMode)
1470 return CommBinaryEcho(&cv,(PCHAR)&b,1);
1471 else
1472 return CommTextEcho(&cv,(PCHAR)&b,1);
1473 }
1474
1475 // �������������������������g��
1476 // - BinaryMode == true
1477 // - FileBracketMode == false
1478 // - cv.TelFlag == false
1479 // - ts.LocalEcho == 0
1480 void FileSendBinayBoost()
1481 {
1482 WORD c, fc;
1483 LONG BCOld;
1484 DWORD read_bytes;
1485
1486 if ((SendDlg == NULL) ||
1487 ((cv.FilePause & OpSendFile) != 0))
1488 return;
1489
1490 BCOld = SendVar->ByteCount;
1491
1492 if (FileRetrySend)
1493 {
1494 c = CommRawOut(&cv, &(FileSendHandler.buf[FileSendHandler.pos]),
1495 FileSendHandler.end - FileSendHandler.pos);
1496 FileSendHandler.pos += c;
1497 FileRetrySend = (FileSendHandler.end != FileSendHandler.pos);
1498 if (FileRetrySend)
1499 return;
1500 }
1501
1502 do {
1503 if (FileSendHandler.pos == FileSendHandler.end) {
1504 ReadFile(SendVar->FileHandle, &(FileSendHandler.buf[0]), sizeof(FileSendHandler.buf), &read_bytes, NULL);
1505 fc = LOWORD(read_bytes);
1506 FileSendHandler.pos = 0;
1507 FileSendHandler.end = fc;
1508 } else {
1509 fc = FileSendHandler.end - FileSendHandler.end;
1510 }
1511
1512 if (fc != 0)
1513 {
1514 c = CommRawOut(&cv, &(FileSendHandler.buf[FileSendHandler.pos]),
1515 FileSendHandler.end - FileSendHandler.pos);
1516 FileSendHandler.pos += c;
1517 FileRetrySend = (FileSendHandler.end != FileSendHandler.pos);
1518 SendVar->ByteCount = SendVar->ByteCount + c;
1519 if (FileRetrySend)
1520 {
1521 if (SendVar->ByteCount != BCOld)
1522 SendDlg->RefreshNum();
1523 return;
1524 }
1525 }
1526 FileDlgRefresh = SendVar->ByteCount;
1527 SendDlg->RefreshNum();
1528 BCOld = SendVar->ByteCount;
1529 if (fc != 0)
1530 return;
1531 } while (fc != 0);
1532
1533 FileTransEnd(OpSendFile);
1534 }
1535
1536 void FileSend()
1537 {
1538 WORD c, fc;
1539 LONG BCOld;
1540 DWORD read_bytes;
1541
1542 if (cv.PortType == IdSerial && ts.FileSendHighSpeedMode &&
1543 BinaryMode && !FileBracketMode && !cv.TelFlag &&
1544 (ts.LocalEcho == 0) && (ts.Baud >= 115200)) {
1545 return FileSendBinayBoost();
1546 }
1547
1548 if ((SendDlg==NULL) ||
1549 ((cv.FilePause & OpSendFile) !=0))
1550 return;
1551
1552 BCOld = SendVar->ByteCount;
1553
1554 if (FileRetrySend)
1555 {
1556 FileRetryEcho = (ts.LocalEcho>0);
1557 c = FSOut1(FileByte);
1558 FileRetrySend = (c==0);
1559 if (FileRetrySend)
1560 return;
1561 }
1562
1563 if (FileRetryEcho)
1564 {
1565 c = FSEcho1(FileByte);
1566 FileRetryEcho = (c==0);
1567 if (FileRetryEcho)
1568 return;
1569 }
1570
1571 do {
1572 if (FileBracketMode == FS_BRACKET_START) {
1573 FileByte = BracketStartStr[FileBracketPtr++];
1574 fc = 1;
1575
1576 if (FileBracketPtr >= sizeof(BracketStartStr) - 1) {
1577 FileBracketMode = FS_BRACKET_END;
1578 FileBracketPtr = 0;
1579 BinaryMode = ts.TransBin;
1580 }
1581 }
1582 else if (! FileReadEOF) {
1583 ReadFile(SendVar->FileHandle, &FileByte, 1, &read_bytes, NULL);
1584 fc = LOWORD(read_bytes);
1585 SendVar->ByteCount = SendVar->ByteCount + fc;
1586
1587 if (FileCRSend && (fc==1) && (FileByte==0x0A)) {
1588 ReadFile(SendVar->FileHandle, &FileByte, 1, &read_bytes, NULL);
1589 fc = LOWORD(read_bytes);
1590 SendVar->ByteCount = SendVar->ByteCount + fc;
1591 }
1592 }
1593 else {
1594 fc = 0;
1595 }
1596
1597 if (fc == 0 && FileBracketMode == FS_BRACKET_END) {
1598 FileReadEOF = TRUE;
1599 FileByte = BracketEndStr[FileBracketPtr++];
1600 fc = 1;
1601 BinaryMode = TRUE;
1602
1603 if (FileBracketPtr >= sizeof(BracketEndStr) - 1) {
1604 FileBracketMode = FS_BRACKET_NONE;
1605 FileBracketPtr = 0;
1606 }
1607 }
1608
1609
1610 if (fc!=0)
1611 {
1612 c = FSOut1(FileByte);
1613 FileCRSend = (ts.TransBin==0) && (FileByte==0x0D);
1614 FileRetrySend = (c==0);
1615 if (FileRetrySend)
1616 {
1617 if (SendVar->ByteCount != BCOld)
1618 SendDlg->RefreshNum();
1619 return;
1620 }
1621 if (ts.LocalEcho>0)
1622 {
1623 c = FSEcho1(FileByte);
1624 FileRetryEcho = (c==0);
1625 if (FileRetryEcho)
1626 return;
1627 }
1628 }
1629 if ((fc==0) || ((SendVar->ByteCount % 100 == 0) && (FileBracketPtr == 0))) {
1630 SendDlg->RefreshNum();
1631 BCOld = SendVar->ByteCount;
1632 if (fc!=0)
1633 return;
1634 }
1635 } while (fc!=0);
1636
1637 FileTransEnd(OpSendFile);
1638 }
1639
1640 void FLogChangeButton(BOOL Pause)
1641 {
1642 if (FLogDlg!=NULL)
1643 FLogDlg->ChangeButton(Pause);
1644 }
1645
1646 void FLogRefreshNum()
1647 {
1648 if (FLogDlg!=NULL)
1649 FLogDlg->RefreshNum();
1650 }
1651
1652 BOOL OpenProtoDlg(PFileVar fv, int IdProto, int Mode, WORD Opt1, WORD Opt2)
1653 {
1654 int vsize;
1655 PProtoDlg pd;
1656
1657 ProtoId = IdProto;
1658
1659 switch (ProtoId) {
1660 case PROTO_KMT:
1661 vsize = sizeof(TKmtVar);
1662 break;
1663 case PROTO_XM:
1664 vsize = sizeof(TXVar);
1665 break;
1666 case PROTO_YM:
1667 vsize = sizeof(TYVar);
1668 break;
1669 case PROTO_ZM:
1670 vsize = sizeof(TZVar);
1671 break;
1672 case PROTO_BP:
1673 vsize = sizeof(TBPVar);
1674 break;
1675 case PROTO_QV:
1676 vsize = sizeof(TQVVar);
1677 break;
1678 default:
1679 vsize = 0;
1680 assert(FALSE);
1681 break;
1682 }
1683 ProtoVar = (PCHAR)malloc(vsize);
1684 if (ProtoVar==NULL)
1685 return FALSE;
1686
1687 switch (ProtoId) {
1688 case PROTO_KMT:
1689 ((PKmtVar)ProtoVar)->KmtMode = Mode;
1690 break;
1691 case PROTO_XM:
1692 ((PXVar)ProtoVar)->XMode = Mode;
1693 ((PXVar)ProtoVar)->XOpt = Opt1;
1694 ((PXVar)ProtoVar)->TextFlag = 1 - (Opt2 & 1);
1695 break;
1696 case PROTO_YM:
1697 ((PYVar)ProtoVar)->YMode = Mode;
1698 ((PYVar)ProtoVar)->YOpt = Opt1;
1699 break;
1700 case PROTO_ZM:
1701 ((PZVar)ProtoVar)->BinFlag = (Opt1 & 1) != 0;
1702 ((PZVar)ProtoVar)->ZMode = Mode;
1703 break;
1704 case PROTO_BP:
1705 ((PBPVar)ProtoVar)->BPMode = Mode;
1706 break;
1707 case PROTO_QV:
1708 ((PQVVar)ProtoVar)->QVMode = Mode;
1709 break;
1710 }
1711
1712 pd = new CProtoDlg();
1713 if (pd==NULL)
1714 {
1715 free(ProtoVar);
1716 ProtoVar = NULL;
1717 return FALSE;
1718 }
1719 pd->Create(hInst, HVTWin, fv, &ts);
1720
1721 (*ProtoInit)(ProtoId,FileVar,ProtoVar,&cv,&ts);
1722
1723 PtDlg = pd;
1724 return TRUE;
1725 }
1726
1727 void CloseProtoDlg()
1728 {
1729 if (PtDlg!=NULL)
1730 {
1731 PtDlg->DestroyWindow();
1732 PtDlg = NULL;
1733
1734 ::KillTimer(FileVar->HMainWin,IdProtoTimer);
1735 if ((ProtoId==PROTO_QV) &&
1736 (((PQVVar)ProtoVar)->QVMode==IdQVSend))
1737 CommTextOut(&cv,"\015",1);
1738 if (FileVar->LogFlag)
1739 CloseHandle(FileVar->LogFile);
1740 FileVar->LogFile = 0;
1741 if (ProtoVar!=NULL)
1742 {
1743 free(ProtoVar);
1744 ProtoVar = NULL;
1745 }
1746 }
1747 }
1748
1749 BOOL ProtoStart()
1750 {
1751 if (cv.ProtoFlag)
1752 return FALSE;
1753 if (FSend)
1754 {
1755 FreeFileVar(&FileVar);
1756 return FALSE;
1757 }
1758
1759 if (! LoadTTFILE())
1760 return FALSE;
1761 NewFileVar(&FileVar);
1762
1763 if (FileVar==NULL)
1764 {
1765 FreeTTFILE();
1766 return FALSE;
1767 }
1768 cv.ProtoFlag = TRUE;
1769 return TRUE;
1770 }
1771
1772 void ProtoEnd()
1773 {
1774 if (! cv.ProtoFlag)
1775 return;
1776 cv.ProtoFlag = FALSE;
1777
1778 /* Enable transmit delay (serial port) */
1779 cv.DelayFlag = TRUE;
1780 TalkStatus = IdTalkKeyb;
1781
1782 CloseProtoDlg();
1783
1784 if ((FileVar!=NULL) && FileVar->Success)
1785 EndDdeCmnd(1);
1786 else
1787 EndDdeCmnd(0);
1788
1789 FreeTTFILE();
1790 FreeFileVar(&FileVar);
1791 }
1792
1793 int ProtoDlgParse()
1794 {
1795 int P;
1796
1797 P = ActiveWin;
1798 if (PtDlg==NULL)
1799 return P;
1800
1801 if ((*ProtoParse)(ProtoId,FileVar,ProtoVar,&cv))
1802 P = 0; /* continue */
1803 else {
1804 CommSend(&cv);
1805 ProtoEnd();
1806 }
1807 return P;
1808 }
1809
1810 void ProtoDlgTimeOut()
1811 {
1812 if (PtDlg!=NULL)
1813 (*ProtoTimeOutProc)(ProtoId,FileVar,ProtoVar,&cv);
1814 }
1815
1816 void ProtoDlgCancel()
1817 {
1818 if ((PtDlg!=NULL) &&
1819 (*ProtoCancel)(ProtoId,FileVar,ProtoVar,&cv))
1820 ProtoEnd();
1821 }
1822
1823 void KermitStart(int mode)
1824 {
1825 WORD w;
1826
1827 if (! ProtoStart())
1828 return;
1829
1830 switch (mode) {
1831 case IdKmtSend:
1832 FileVar->OpId = OpKmtSend;
1833 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1834 {
1835 char FileDirExpanded[MAX_PATH];
1836 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1837 if (!(*GetMultiFname)(FileVar, FileDirExpanded, GMF_KERMIT, &w) ||
1838 (FileVar->NumFname==0))
1839 {
1840 ProtoEnd();
1841 return;
1842 }
1843 }
1844 else
1845 (*SetFileVar)(FileVar);
1846 break;
1847 case IdKmtReceive:
1848 FileVar->OpId = OpKmtRcv;
1849 break;
1850 case IdKmtGet:
1851 FileVar->OpId = OpKmtSend;
1852 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1853 {
1854 if (! (*GetGetFname)(FileVar->HMainWin,FileVar) ||
1855 (strlen(FileVar->FullName)==0))
1856 {
1857 ProtoEnd();
1858 return;
1859 }
1860 }
1861 else
1862 (*SetFileVar)(FileVar);
1863 break;
1864 case IdKmtFinish:
1865 FileVar->OpId = OpKmtFin;
1866 break;
1867 default:
1868 ProtoEnd();
1869 return;
1870 }
1871 TalkStatus = IdTalkQuiet;
1872
1873 /* disable transmit delay (serial port) */
1874 cv.DelayFlag = FALSE;
1875
1876 if (! OpenProtoDlg(FileVar,PROTO_KMT,mode,0,0))
1877 ProtoEnd();
1878 }
1879
1880 void XMODEMStart(int mode)
1881 {
1882 LONG Option;
1883 int tmp;
1884
1885 if (! ProtoStart())
1886 return;
1887
1888 if (mode==IdXReceive)
1889 FileVar->OpId = OpXRcv;
1890 else
1891 FileVar->OpId = OpXSend;
1892
1893 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1894 {
1895 char FileDirExpanded[MAX_PATH];
1896 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1897 Option = MAKELONG(ts.XmodemBin,ts.XmodemOpt);
1898 if (! (*GetXFname)(FileVar->HMainWin,
1899 mode==IdXReceive,&Option,FileVar,FileDirExpanded))
1900 {
1901 ProtoEnd();
1902 return;
1903 }
1904 tmp = HIWORD(Option);
1905 if (mode == IdXReceive) {
1906 if (IsXoptCRC(tmp)) {
1907 if (IsXopt1k(ts.XmodemOpt)) {
1908 ts.XmodemOpt = Xopt1kCRC;
1909 }
1910 else {
1911 ts.XmodemOpt = XoptCRC;
1912 }
1913 }
1914 else {
1915 if (IsXopt1k(ts.XmodemOpt)) {
1916 ts.XmodemOpt = Xopt1kCksum;
1917 }
1918 else {
1919 ts.XmodemOpt = XoptCheck;
1920 }
1921 }
1922 ts.XmodemBin = LOWORD(Option);
1923 }
1924 else {
1925 if (IsXopt1k(tmp)) {
1926 if (IsXoptCRC(ts.XmodemOpt)) {
1927 ts.XmodemOpt = Xopt1kCRC;
1928 }
1929 else {
1930 ts.XmodemOpt = Xopt1kCksum;
1931 }
1932 }
1933 else {
1934 if (IsXoptCRC(ts.XmodemOpt)) {
1935 ts.XmodemOpt = XoptCRC;
1936 }
1937 else {
1938 ts.XmodemOpt = XoptCheck;
1939 }
1940 }
1941 }
1942 }
1943 else
1944 (*SetFileVar)(FileVar);
1945
1946 if (mode==IdXReceive)
1947 FileVar->FileHandle = _lcreat(FileVar->FullName,0);
1948 else
1949 FileVar->FileHandle = _lopen(FileVar->FullName,OF_READ);
1950
1951 FileVar->FileOpen = FileVar->FileHandle != INVALID_HANDLE_VALUE;
1952 if (! FileVar->FileOpen)
1953 {
1954 ProtoEnd();
1955 return;
1956 }
1957 TalkStatus = IdTalkQuiet;
1958
1959 /* disable transmit delay (serial port) */
1960 cv.DelayFlag = FALSE;
1961
1962 if (! OpenProtoDlg(FileVar,PROTO_XM,mode,
1963 ts.XmodemOpt,ts.XmodemBin))
1964 ProtoEnd();
1965 }
1966
1967 void YMODEMStart(int mode)
1968 {
1969 WORD Opt;
1970
1971 if (! ProtoStart())
1972 return;
1973
1974 if (mode==IdYSend)
1975 {
1976 char FileDirExpanded[MAX_PATH];
1977 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
1978
1979 // �t�@�C���]�������I�v�V������"Yopt1K"�����������B
1980 // TODO: "Yopt1K", "YoptG", "YoptSingle"�������������������AIDD_FOPT���g�������K�v�����B
1981 Opt = Yopt1K;
1982 FileVar->OpId = OpYSend;
1983 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
1984 {
1985 if (! (*GetMultiFname)(FileVar,FileDirExpanded,GMF_Y,&Opt) ||
1986 (FileVar->NumFname==0))
1987 {
1988 ProtoEnd();
1989 return;
1990 }
1991 //ts.XmodemBin = Opt;
1992 }
1993 else
1994 (*SetFileVar)(FileVar);
1995 }
1996 else {
1997 FileVar->OpId = OpYRcv;
1998 // �t�@�C���]�������I�v�V������"Yopt1K"�����������B
1999 Opt = Yopt1K;
2000 (*SetFileVar)(FileVar);
2001 }
2002
2003 TalkStatus = IdTalkQuiet;
2004
2005 /* disable transmit delay (serial port) */
2006 cv.DelayFlag = FALSE;
2007
2008 if (! OpenProtoDlg(FileVar,PROTO_YM,mode,Opt,0))
2009 ProtoEnd();
2010 }
2011
2012 void ZMODEMStart(int mode)
2013 {
2014 WORD Opt;
2015
2016 if (! ProtoStart())
2017 return;
2018
2019 if (mode == IdZSend || mode == IdZAutoS)
2020 {
2021 Opt = ts.XmodemBin;
2022 FileVar->OpId = OpZSend;
2023 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
2024 {
2025 char FileDirExpanded[MAX_PATH];
2026 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
2027 if (! (*GetMultiFname)(FileVar,FileDirExpanded,GMF_Z,&Opt) ||
2028 (FileVar->NumFname==0))
2029 {
2030 if (mode == IdZAutoS) {
2031 CommRawOut(&cv, "\030\030\030\030\030\030\030\030\b\b\b\b\b\b\b\b\b\b", 18);
2032 }
2033 ProtoEnd();
2034 return;
2035 }
2036 ts.XmodemBin = Opt;
2037 }
2038 else
2039 (*SetFileVar)(FileVar);
2040 }
2041 else /* IdZReceive or IdZAutoR */
2042 FileVar->OpId = OpZRcv;
2043
2044 TalkStatus = IdTalkQuiet;
2045
2046 /* disable transmit delay (serial port) */
2047 cv.DelayFlag = FALSE;
2048
2049 if (! OpenProtoDlg(FileVar,PROTO_ZM,mode,Opt,0))
2050 ProtoEnd();
2051 }
2052
2053 void BPStart(int mode)
2054 {
2055 LONG Option = 0;
2056
2057 if (! ProtoStart())
2058 return;
2059 if (mode==IdBPSend)
2060 {
2061 FileVar->OpId = OpBPSend;
2062 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
2063 {
2064 char FileDirExpanded[MAX_PATH];
2065 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
2066 FileVar->FullName[0] = 0;
2067 if (! (*GetTransFname)(FileVar, FileDirExpanded, GTF_BP, &Option))
2068 {
2069 ProtoEnd();
2070 return;
2071 }
2072 }
2073 else
2074 (*SetFileVar)(FileVar);
2075 }
2076 else /* IdBPReceive or IdBPAuto */
2077 FileVar->OpId = OpBPRcv;
2078
2079 TalkStatus = IdTalkQuiet;
2080
2081 /* disable transmit delay (serial port) */
2082 cv.DelayFlag = FALSE;
2083
2084 if (! OpenProtoDlg(FileVar,PROTO_BP,mode,0,0))
2085 ProtoEnd();
2086 }
2087
2088 void QVStart(int mode)
2089 {
2090 WORD W;
2091
2092 if (! ProtoStart())
2093 return;
2094
2095 if (mode==IdQVSend)
2096 {
2097 FileVar->OpId = OpQVSend;
2098 if (strlen(&(FileVar->FullName[FileVar->DirLen]))==0)
2099 {
2100 char FileDirExpanded[MAX_PATH];
2101 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
2102 if (! (*GetMultiFname)(FileVar,FileDirExpanded,GMF_QV, &W) ||
2103 (FileVar->NumFname==0))
2104 {
2105 ProtoEnd();
2106 return;
2107 }
2108 }
2109 else
2110 (*SetFileVar)(FileVar);
2111 }
2112 else
2113 FileVar->OpId = OpQVRcv;
2114
2115 TalkStatus = IdTalkQuiet;
2116
2117 /* disable transmit delay (serial port) */
2118 cv.DelayFlag = FALSE;
2119
2120 if (! OpenProtoDlg(FileVar,PROTO_QV,mode,0,0))
2121 ProtoEnd();
2122 }
2123
2124 /**
2125 * ���O���[�e�[�g������
2126 * ���O���T�C�Y��<size>�o�C�g���������������A���[�e�[�V��������������������
2127 */
2128 void LogRotateSize(size_t size)
2129 {
2130 if (LogVar == NULL) {
2131 return;
2132 }
2133 LogVar->RotateMode = ROTATE_SIZE;
2134 LogVar->RotateSize = size;
2135 }
2136
2137 /**
2138 * ���O���[�e�[�g������
2139 * ���O�t�@�C������������������
2140 */
2141 void LogRotateRotate(int step)
2142 {
2143 if (LogVar == NULL) {
2144 return;
2145 }
2146 LogVar->RotateStep = step;
2147 }
2148
2149 /**
2150 * ���O���[�e�[�g������
2151 * ���[�e�[�V���������~
2152 */
2153 void LogRotateHalt(void)
2154 {
2155 if (LogVar == NULL) {
2156 return;
2157 }
2158 LogVar->RotateMode = ROTATE_NONE;
2159 LogVar->RotateSize = 0;
2160 LogVar->RotateStep = 0;
2161 }
2162
2163 static INT_PTR CALLBACK OnCommentDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp)
2164 {
2165 static const DlgTextInfo TextInfos[] = {
2166 { 0, "DLG_COMMENT_TITLE" },
2167 { IDOK, "BTN_OK" }
2168 };
2169 char buf[256];
2170 UINT ret;
2171
2172 switch (msg) {
2173 case WM_INITDIALOG:
2174 //SetDlgItemText(hDlgWnd, IDC_EDIT_COMMENT, "�T���v��");
2175 // �G�f�B�b�g�R���g���[�����t�H�[�J�X��������
2176 SetFocus(GetDlgItem(hDlgWnd, IDC_EDIT_COMMENT));
2177 SetDlgTexts(hDlgWnd, TextInfos, _countof(TextInfos), ts.UILanguageFile);
2178 return FALSE;
2179
2180 case WM_COMMAND:
2181 switch (LOWORD(wp)) {
2182 case IDOK:
2183 memset(buf, 0, sizeof(buf));
2184 ret = GetDlgItemTextA(hDlgWnd, IDC_EDIT_COMMENT, buf, sizeof(buf) - 1);
2185 if (ret > 0) { // �e�L�X�g��������
2186 //buf[sizeof(buf) - 1] = '\0'; // null-terminate
2187 CommentLogToFile(buf, ret);
2188 }
2189 TTEndDialog(hDlgWnd, IDOK);
2190 break;
2191 default:
2192 return FALSE;
2193 }
2194 break;
2195 case WM_CLOSE:
2196 TTEndDialog(hDlgWnd, 0);
2197 return TRUE;
2198
2199 default:
2200 return FALSE;
2201 }
2202 return TRUE;
2203 }
2204
2205 void LogAddCommentDlg(HINSTANCE hInst, HWND hWnd)
2206 {
2207 // ���O�t�@�C�����R�����g���������� (2004.8.6 yutaka)
2208 TTDialogBox(hInst, MAKEINTRESOURCE(IDD_COMMENT_DIALOG),
2209 HVTWin, OnCommentDlgProc);
2210 }
2211
2212 void LogClose()
2213 {
2214 if (LogVar != NULL)
2215 FileTransEnd(OpLog);
2216 }
2217
2218 BOOL LogOpen(const char *fname)
2219 {
2220 BOOL ret;
2221
2222 if ((LogVar==NULL) && !NewFileVar(&LogVar)) {
2223 return FALSE;
2224 }
2225
2226 LogVar->DirLen = 0;
2227 LogVar->NoMsg = TRUE;
2228 strncpy_s(LogVar->FullName, sizeof(LogVar->FullName), fname, _TRUNCATE);
2229 ret = LogStart();
2230 return ret;
2231 }
2232
2233 BOOL LogIsOpend()
2234 {
2235 // LogVar->FileOpen
2236 return LogVar != NULL;
2237 }
2238
2239 void LogWriteStr(const char *str)
2240 {
2241 if (LogVar != NULL)
2242 {
2243 DWORD wrote;
2244 size_t len = strlen(str);
2245 WriteFile(LogVar->FileHandle, str, len, &wrote, NULL);
2246 LogVar->ByteCount =
2247 LogVar->ByteCount + len;
2248 FLogRefreshNum();
2249 }
2250 }
2251
2252 void LogInfo(char *param_ptr, size_t param_len)
2253 {
2254 if (LogVar) {
2255 param_ptr[0] = '0'
2256 + (ts.LogBinary != 0)
2257 + ((ts.Append != 0) << 1)
2258 + ((ts.LogTypePlainText != 0) << 2)
2259 + ((ts.LogTimestamp != 0) << 3)
2260 + ((ts.LogHideDialog != 0) << 4);
2261 strncpy_s(param_ptr + 1, param_len - 1, LogVar->FullName, _TRUNCATE);
2262 }
2263 else {
2264 param_ptr[0] = '0' - 1;
2265 param_ptr[1] = 0;
2266 }
2267 }
2268
2269 /**
2270 * ���������O�t�@�C����������
2271 */
2272 const char *LogGetFilename()
2273 {
2274 if (LogVar == NULL) {
2275 return NULL;
2276 }
2277 return LogVar->FullName;
2278 }
2279
2280 /**
2281 * ���O�_�C�A���O���J��
2282 * @retval TRUE [ok] ����������
2283 * @retval FALSE �L�����Z��������
2284 * @param[in,out] filename OK���A�t�@�C�����A�s�v����������free()��������
2285 */
2286 BOOL LogOpenDialog(char **filename)
2287 {
2288 LogDlgData_t *data = (LogDlgData_t *)calloc(sizeof(LogDlgData_t), 1);
2289 data->filename = LogGetLogFilename(NULL);
2290 INT_PTR ret = TTDialogBoxParam(
2291 hInst, MAKEINTRESOURCE(IDD_LOGDLG),
2292 HVTWin, LogFnHook, (LPARAM)data);
2293 if (ret == IDOK) {
2294 *filename = data->filename;
2295 }
2296 free(data);
2297 return ret == IDOK ? TRUE : FALSE;
2298 }
2299
2300 /**
2301 * ���O�t�@�C����������
2302 * ���O�t�@�C�����p���C�����s��
2303 * - strftime() ���������t�W�J
2304 * - �������������O�t�@�C���t�H���_������
2305 * - �z�X�g��,�|�[�g�����W�J
2306 *
2307 * @param[in] log_filename �t�@�C����(����/��������������ok)
2308 * NULL�������f�t�H���g�t�@�C����������
2309 * strftime�`��ok
2310 * @return �t���p�X�t�@�C����
2311 * �s�v���������� free() ��������
2312 */
2313 char *LogGetLogFilename(const char *log_filename)
2314 {
2315 // �t�H���_
2316 char FileDirExpanded[MAX_PATH];
2317 char *logdir;
2318 if (strlen(ts.LogDefaultPath) > 0) {
2319 logdir = ts.LogDefaultPath;
2320 }
2321 else if (strlen(ts.FileDir) > 0) {
2322 ExpandEnvironmentStrings(ts.FileDir, FileDirExpanded, sizeof(FileDirExpanded));
2323 logdir = FileDirExpanded;
2324 }
2325 else {
2326 logdir = ts.HomeDir;
2327 }
2328
2329 // ���������t�@�C����
2330 char base_name[MAX_PATH];
2331 if (log_filename == NULL) {
2332 strncpy_s(base_name, _countof(base_name), ts.LogDefaultName, _TRUNCATE);
2333 }
2334 else {
2335 strncpy_s(base_name, _countof(base_name), log_filename, _TRUNCATE);
2336 }
2337
2338 // �t���p�X��
2339 char full_path[MAX_PATH];
2340 ConvFName(logdir, base_name, sizeof(base_name), "", full_path, sizeof(full_path));
2341 ParseStrftimeFileName(full_path, sizeof(full_path));
2342 ConvertLogname(full_path, sizeof(full_path));
2343
2344 return _strdup(full_path);
2345 }

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