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 8866 - (show annotations) (download) (as text)
Wed Jul 29 14:39:44 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: 59442 byte(s)
Appendラジオボタンの動作を修正

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

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