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 8860 - (show annotations) (download) (as text)
Sat Jul 25 16:00:24 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: 56848 byte(s)
マクロ(ttmacro)用送信バッファの分離

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

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