Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/filesys_log.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8858 - (hide annotations) (download) (as text)
Sat Jul 25 16:00:00 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: 57441 byte(s)
API名を修正

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

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