svnno****@sourc*****
svnno****@sourc*****
2010年 4月 12日 (月) 22:43:07 JST
Revision: 3855 http://sourceforge.jp/projects/ttssh2/svn/view?view=rev&revision=3855 Author: yutakapon Date: 2010-04-12 22:43:07 +0900 (Mon, 12 Apr 2010) Log Message: ----------- Z. Vickery æ°ã®ããããé©ç¨ããã Modified Paths: -------------- trunk/teraterm/teraterm/commlib.c trunk/teraterm/ttpfile/ttfile.c trunk/teraterm/ttpfile/xmodem.c trunk/teraterm/ttpfile/ymodem.c -------------- next part -------------- Modified: trunk/teraterm/teraterm/commlib.c =================================================================== --- trunk/teraterm/teraterm/commlib.c 2010-04-12 12:51:24 UTC (rev 3854) +++ trunk/teraterm/teraterm/commlib.c 2010-04-12 13:43:07 UTC (rev 3855) @@ -1,1148 +1,1149 @@ -/* Tera Term - Copyright(C) 1994-1998 T. Teranishi - All rights reserved. */ -/* IPv6 modification is Copyright (C) 2000, 2001 Jun-ya KATO <kato****@win6*****> */ - -/* TERATERM.EXE, Communication routines */ -#include "teraterm.h" -#include "tttypes.h" -#include "tt_res.h" -#include <process.h> - -#include "ttcommon.h" -#include "ttwsk.h" -#include "ttlib.h" -#include "ttfileio.h" -#include "ttplug.h" /* TTPLUG */ - -#include "commlib.h" -#ifndef NO_INET6 -#include <winsock2.h> -#include <ws2tcpip.h> -#include <stdio.h> /* for _snprintf() */ -#include "WSAAsyncGetAddrInfo.h" -#endif /* NO_INET6 */ -#include <time.h> - -static SOCKET OpenSocket(PComVar); -static void AsyncConnect(PComVar); -static int CloseSocket(SOCKET); - -/* create socket */ -static SOCKET OpenSocket(PComVar cv) -{ - cv->s = cv->res->ai_family; - cv->s = Psocket(cv->res->ai_family, cv->res->ai_socktype, cv->res->ai_protocol); - return cv->s; -} - -/* connect with asynchronous mode */ -static void AsyncConnect(PComVar cv) -{ - int Err; - BOOL BBuf; - BBuf = TRUE; - /* set synchronous mode */ - PWSAAsyncSelect(cv->s,cv->HWin,0,0); - Psetsockopt(cv->s,(int)SOL_SOCKET,SO_OOBINLINE,(char FAR *)&BBuf,sizeof(BBuf)); - /* set asynchronous mode */ - PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMOPEN, FD_CONNECT); - - // zXgÖÌÚ±ÉêèÔ§ÂÆA§IÉ\PbgðN[YµÄA - // Ú±ðLZ³¹éBlª0ÌêͽàµÈ¢B - // (2007.1.11 yutaka) - if (*cv->ConnetingTimeout > 0) { - SetTimer(cv->HWin, IdCancelConnectTimer, *cv->ConnetingTimeout * 1000, NULL); - } - - /* WM_USER_COMMOPEN occurs, CommOpen is called, then CommStart is called */ - Err = Pconnect(cv->s, cv->res->ai_addr, cv->res->ai_addrlen); - if (Err != 0) { - Err = PWSAGetLastError(); - if (Err == WSAEWOULDBLOCK) { - /* Do nothing */ - } else if (Err!=0 ) { - PostMessage(cv->HWin, WM_USER_COMMOPEN,0, - MAKELONG(FD_CONNECT,Err)); - } - } -} - -/* close socket */ -static int CloseSocket(SOCKET s) -{ - return Pclosesocket(s); -} - -#define CommInQueSize 8192 -#define CommOutQueSize 2048 -#define CommXonLim 2048 -#define CommXoffLim 2048 - -#define READENDNAME "ReadEnd" -#define WRITENAME "Write" -#define READNAME "Read" -#define PRNWRITENAME "PrnWrite" - -static HANDLE ReadEnd; -static OVERLAPPED wol, rol; - -// Winsock async operation handle -static HANDLE HAsync=0; - -BOOL TCPIPClosed = TRUE; - -/* Printer port handle for - direct pass-thru printing */ -static HANDLE PrnID = INVALID_HANDLE_VALUE; -static BOOL LPTFlag; - -// Initialize ComVar. -// This routine is called only once -// by the initialization procedure of Tera Term. -void CommInit(PComVar cv) -{ - cv->Open = FALSE; - cv->Ready = FALSE; - -// log-buffer variables - cv->HLogBuf = 0; - cv->HBinBuf = 0; - cv->LogBuf = NULL; - cv->BinBuf = NULL; - cv->LogPtr = 0; - cv->LStart = 0; - cv->LCount = 0; - cv->BinPtr = 0; - cv->BStart = 0; - cv->BCount = 0; - cv->DStart = 0; - cv->DCount = 0; - cv->BinSkip = 0; - cv->FilePause = 0; - cv->ProtoFlag = FALSE; -/* message flag */ - cv->NoMsg = 0; -} - -/* reset a serial port which is already open */ -void CommResetSerial(PTTSet ts, PComVar cv, BOOL ClearBuff) -{ - DCB dcb; - DWORD DErr; - COMMTIMEOUTS ctmo; - - if (! cv->Open || - (cv->PortType != IdSerial)) { - return; - } - - ClearCommError(cv->ComID,&DErr,NULL); - SetupComm(cv->ComID,CommInQueSize,CommOutQueSize); - /* flush input and output buffers */ - if (ClearBuff) { - PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT | - PURGE_TXCLEAR | PURGE_RXCLEAR); - } - - memset(&ctmo,0,sizeof(ctmo)); - ctmo.ReadIntervalTimeout = MAXDWORD; - ctmo.WriteTotalTimeoutConstant = 500; - SetCommTimeouts(cv->ComID,&ctmo); - cv->InBuffCount = 0; - cv->InPtr = 0; - cv->OutBuffCount = 0; - cv->OutPtr = 0; - - cv->DelayPerChar = ts->DelayPerChar; - cv->DelayPerLine = ts->DelayPerLine; - - memset(&dcb,0,sizeof(DCB)); - dcb.DCBlength = sizeof(DCB); - dcb.BaudRate = GetCommSerialBaudRate(ts->Baud); - dcb.fBinary = TRUE; - switch (ts->Parity) { - case IdParityEven: - dcb.fParity = TRUE; - dcb.Parity = EVENPARITY; - break; - case IdParityOdd: - dcb.fParity = TRUE; - dcb.Parity = ODDPARITY; - break; - case IdParityNone: - dcb.Parity = NOPARITY; - break; - } - - dcb.fDtrControl = DTR_CONTROL_ENABLE; - dcb.fRtsControl = RTS_CONTROL_ENABLE; - switch (ts->Flow) { - case IdFlowX: - dcb.fOutX = TRUE; - dcb.fInX = TRUE; - dcb.XonLim = CommXonLim; - dcb.XoffLim = CommXoffLim; - dcb.XonChar = XON; - dcb.XoffChar = XOFF; - break; - case IdFlowHard: - dcb.fOutxCtsFlow = TRUE; - dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; - break; - } - - switch (ts->DataBit) { - case IdDataBit7: - dcb.ByteSize = 7; - break; - case IdDataBit8: - dcb.ByteSize = 8; - break; - } - switch (ts->StopBit) { - case IdStopBit1: - dcb.StopBits = ONESTOPBIT; - break; - case IdStopBit2: - dcb.StopBits = TWOSTOPBITS; - break; - } - - SetCommState(cv->ComID, &dcb); - - /* enable receive request */ - SetCommMask(cv->ComID,0); - SetCommMask(cv->ComID,EV_RXCHAR); -} - -void CommOpen(HWND HW, PTTSet ts, PComVar cv) -{ -#ifdef NO_INET6 - int Err; -#endif /* NO_INET6 */ - char ErrMsg[21]; - char P[50]; - - MSG Msg; -#ifndef NO_INET6 - ADDRINFO hints; - char pname[NI_MAXSERV]; -#else - char HEntBuff[MAXGETHOSTSTRUCT]; - u_long addr; - SOCKADDR_IN saddr; -#endif /* NO_INET6 */ - - BOOL InvalidHost; -#ifdef NO_INET6 - BOOL BBuf; -#endif /* NO_INET6 */ - - char uimsg[MAX_UIMSG]; - - /* initialize ComVar */ - cv->InBuffCount = 0; - cv->InPtr = 0; - cv->OutBuffCount = 0; - cv->OutPtr = 0; - cv->HWin = HW; - cv->Ready = FALSE; - cv->Open = FALSE; - cv->PortType = ts->PortType; - cv->ComPort = 0; - cv->RetryCount = 0; -#ifndef NO_INET6 - cv->RetryWithOtherProtocol = TRUE; -#endif /* NO_INET6 */ - cv->s = INVALID_SOCKET; - cv->ComID = INVALID_HANDLE_VALUE; - cv->CanSend = TRUE; - cv->RRQ = FALSE; - cv->SendKanjiFlag = FALSE; - cv->SendCode = IdASCII; - cv->EchoKanjiFlag = FALSE; - cv->EchoCode = IdASCII; - cv->Language = ts->Language; - cv->CRSend = ts->CRSend; - cv->KanjiCodeEcho = ts->KanjiCode; - cv->JIS7KatakanaEcho = ts->JIS7Katakana; - cv->KanjiCodeSend = ts->KanjiCodeSend; - cv->JIS7KatakanaSend = ts->JIS7KatakanaSend; - cv->KanjiIn = ts->KanjiIn; - cv->KanjiOut = ts->KanjiOut; - cv->RussHost = ts->RussHost; - cv->RussClient = ts->RussClient; - cv->DelayFlag = TRUE; - cv->DelayPerChar = ts->DelayPerChar; - cv->DelayPerLine = ts->DelayPerLine; - cv->TelBinRecv = FALSE; - cv->TelBinSend = FALSE; - cv->TelFlag = FALSE; - cv->TelMode = FALSE; - cv->IACFlag = FALSE; - cv->TelCRFlag = FALSE; - cv->TelCRSend = FALSE; - cv->TelCRSendEcho = FALSE; - cv->TelAutoDetect = ts->TelAutoDetect; /* TTPLUG */ - cv->Locale = ts->Locale; - cv->CodePage = &ts->CodePage; - cv->ConnetingTimeout = &ts->ConnectingTimeout; - cv->LastSendTime = time(NULL); - cv->LineModeBuffCount = 0; - cv->Flush = FALSE; - cv->FlushLen = 0; - cv->TelLineMode = FALSE; - - if ((ts->PortType!=IdSerial) && (strlen(ts->HostName)==0)) - { - PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); - return; - } - - switch (ts->PortType) { - case IdTCPIP: - cv->TelFlag = (ts->Telnet > 0); - if (ts->EnableLineMode) { - cv->TelLineMode = TRUE; - } - if (! LoadWinsock()) { - if (cv->NoMsg==0) { - get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); - get_lang_msg("MSG_WINSOCK_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot use winsock", ts->UILanguageFile); - MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); - } - InvalidHost = TRUE; - } - else { - TTXOpenTCP(); /* TTPLUG */ - cv->Open = TRUE; -#ifndef NO_INET6 - /* resolving address */ - memset(&hints, 0, sizeof(hints)); - hints.ai_family = ts->ProtocolFamily; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - _snprintf_s(pname, sizeof(pname), _TRUNCATE, "%d", ts->TCPPort); - - HAsync = WSAAsyncGetAddrInfo(HW, WM_USER_GETHOST, - ts->HostName, pname, &hints, &cv->res0); - if (HAsync == 0) - InvalidHost = TRUE; - else { - cv->ComPort = 1; // set "getting host" flag - // (see CVTWindow::OnSysCommand()) - do { - if (GetMessage(&Msg,0,0,0)) { - if ((Msg.hwnd==HW) && - ((Msg.message == WM_SYSCOMMAND) && - ((Msg.wParam & 0xfff0) == SC_CLOSE) || - (Msg.message == WM_COMMAND) && - (LOWORD(Msg.wParam) == ID_FILE_EXIT) || - (Msg.message == WM_CLOSE))) { /* Exit when the user closes Tera Term */ - PWSACancelAsyncRequest(HAsync); - CloseHandle(HAsync); - HAsync = 0; - cv->ComPort = 0; // clear "getting host" flag - PostMessage(HW,Msg.message,Msg.wParam,Msg.lParam); - return; - } - if (Msg.message != WM_USER_GETHOST) { /* Prosess messages */ - TranslateMessage(&Msg); - DispatchMessage(&Msg); - } - } - else { - return; - } - } while (Msg.message!=WM_USER_GETHOST); - cv->ComPort = 0; // clear "getting host" flag - CloseHandle(HAsync); - HAsync = 0; - InvalidHost = WSAGETASYNCERROR(Msg.lParam) != 0; - } - } /* if (!LoadWinsock()) */ - - if (InvalidHost) { - if (cv->NoMsg==0) { - get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); - get_lang_msg("MSG_INVALID_HOST_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Invalid host", ts->UILanguageFile); - MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); - } - goto BreakSC; - } - for (cv->res = cv->res0; cv->res; cv->res = cv->res->ai_next) { - cv->s = OpenSocket(cv); - if (cv->s == INVALID_SOCKET) { - CloseSocket(cv->s); - continue; - } - /* start asynchronous connect */ - AsyncConnect(cv); - break; /* break for-loop immediately */ - } - break; -#else - if ((ts->HostName[0] >= 0x30) && (ts->HostName[0] <= 0x39)) - { - addr = Pinet_addr(ts->HostName); - InvalidHost = (addr == 0xffffffff); - } - else { - HAsync = PWSAAsyncGetHostByName(HW,WM_USER_GETHOST, - ts->HostName,HEntBuff,sizeof(HEntBuff)); - if (HAsync == 0) - InvalidHost = TRUE; - else { - cv->ComPort = 1; // set "getting host" flag - // (see CVTWindow::OnSysCommand()) - do { - if (GetMessage(&Msg,0,0,0)) - { - if ((Msg.hwnd==HW) && - ((Msg.message == WM_SYSCOMMAND) && - ((Msg.wParam & 0xfff0) == SC_CLOSE) || - (Msg.message == WM_COMMAND) && - (LOWORD(Msg.wParam) == ID_FILE_EXIT) || - (Msg.message == WM_CLOSE))) - { /* Exit when the user closes Tera Term */ - PWSACancelAsyncRequest(HAsync); - HAsync = 0; - cv->ComPort = 0; // clear "getting host" flag - PostMessage(HW,Msg.message,Msg.wParam,Msg.lParam); - return; - } - if (Msg.message != WM_USER_GETHOST) - { /* Prosess messages */ - TranslateMessage(&Msg); - DispatchMessage(&Msg); - } - } - else { - return; - } - } while (Msg.message!=WM_USER_GETHOST); - cv->ComPort = 0; // clear "getting host" flag - HAsync = 0; - InvalidHost = WSAGETASYNCERROR(Msg.lParam) != 0; - if (! InvalidHost) - { - if (((PHOSTENT)HEntBuff)->h_addr_list != NULL) - memcpy(&addr, - ((PHOSTENT)HEntBuff)->h_addr_list[0],sizeof(addr)); - else - InvalidHost = TRUE; - } - } - - } - - if (InvalidHost) - { - if (cv->NoMsg==0) - MessageBox(cv->HWin,"Invalid host",ErrorCaption, - MB_TASKMODAL | MB_ICONEXCLAMATION); - } - else { - cv->s= Psocket(AF_INET,SOCK_STREAM,IPPROTO_TCP); - if (cv->s==INVALID_SOCKET) - { - InvalidHost = TRUE; - if (cv->NoMsg==0) - MessageBox(cv->HWin,ErrorCantConn,ErrorCaption, - MB_TASKMODAL | MB_ICONEXCLAMATION); - } - else { - BBuf = TRUE; - Psetsockopt(cv->s,(int)SOL_SOCKET,SO_OOBINLINE,(char FAR *)&BBuf,sizeof(BBuf)); - - PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMOPEN, FD_CONNECT); - saddr.sin_family = AF_INET; - saddr.sin_port = Phtons(ts->TCPPort); - saddr.sin_addr.s_addr = addr; - memset(saddr.sin_zero,0,8); - - Err = Pconnect(cv->s,(LPSOCKADDR)&saddr,sizeof(saddr)); - if (Err!=0 ) Err = PWSAGetLastError(); - if (Err==WSAEWOULDBLOCK ) - { - /* Do nothing */ - } - else if (Err!=0 ) - PostMessage(cv->HWin, WM_USER_COMMOPEN,0, - MAKELONG(FD_CONNECT,Err)); - } - } - } - break; -#endif /* NO_INET6 */ - - case IdSerial: - InitFileIO(IdSerial); /* TTPLUG */ - TTXOpenFile(); /* TTPLUG */ - _snprintf_s(P, sizeof(P), _TRUNCATE, "COM%d", ts->ComPort); - strncpy_s(ErrMsg, sizeof(ErrMsg),P, _TRUNCATE); - strncpy_s(P, sizeof(P),"\\\\.\\", _TRUNCATE); - strncat_s(P, sizeof(P),ErrMsg, _TRUNCATE); - cv->ComID = - PCreateFile(P,GENERIC_READ | GENERIC_WRITE, - 0,NULL,OPEN_EXISTING, - FILE_FLAG_OVERLAPPED,NULL); - if (cv->ComID == INVALID_HANDLE_VALUE ) { - get_lang_msg("MSG_CANTOEPN_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s", ts->UILanguageFile); - _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4]); - - if (cv->NoMsg==0) { - get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); - MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); - } - InvalidHost = TRUE; - } - else { - cv->Open = TRUE; - cv->ComPort = ts->ComPort; - CommResetSerial(ts, cv, ts->ClearComBuffOnOpen); - if (!ts->ClearComBuffOnOpen) { - cv->RRQ = TRUE; - } - - /* notify to VT window that Comm Port is open */ - PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0); - InvalidHost = FALSE; - - SetCOMFlag(ts->ComPort); - } - break; /* end of "case IdSerial:" */ - - case IdFile: - InitFileIO(IdFile); /* TTPLUG */ - TTXOpenFile(); /* TTPLUG */ - cv->ComID = PCreateFile(ts->HostName,GENERIC_READ,0,NULL, - OPEN_EXISTING,0,NULL); - InvalidHost = (cv->ComID == INVALID_HANDLE_VALUE); - if (InvalidHost) { - if (cv->NoMsg==0) { - get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); - get_lang_msg("MSG_CANTOEPN_FILE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open file", ts->UILanguageFile); - MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); - } - } - else { - cv->Open = TRUE; - PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0); - } - break; - } /* end of "switch" */ - -#ifndef NO_INET6 -BreakSC: -#endif /* NO_INET6 */ - if (InvalidHost) { - PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); - if ( (ts->PortType==IdTCPIP) && cv->Open ) { - if ( cv->s!=INVALID_SOCKET ) { - Pclosesocket(cv->s); - } - FreeWinsock(); - } - return; - } -} - -void CommThread(void *arg) -{ - DWORD Evt; - PComVar cv = (PComVar)arg; - DWORD DErr; - HANDLE REnd; - char Temp[20]; - - _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort); - REnd = OpenEvent(EVENT_ALL_ACCESS,FALSE, Temp); - while (TRUE) { - if (WaitCommEvent(cv->ComID,&Evt,NULL)) { - if (! cv->Ready) { - _endthread(); - } - if (! cv->RRQ) { - PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_READ); - } - WaitForSingleObject(REnd,INFINITE); - } - else { - if (! cv->Ready) { - _endthread(); - } - ClearCommError(cv->ComID,&DErr,NULL); - } - } -} - -void CommStart(PComVar cv, LONG lParam, PTTSet ts) -{ - char ErrMsg[31]; - char Temp[20]; - char uimsg[MAX_UIMSG]; - - if (! cv->Open ) { - return; - } - if ( cv->Ready ) { - return; - } - - // LZ^C}ª êÎæèÁ·B½¾µA±Ì_Å WM_TIMER ªçêÄ¢éÂ\«Í éB - if (*cv->ConnetingTimeout > 0) { - KillTimer(cv->HWin, IdCancelConnectTimer); - } - - switch (cv->PortType) { - case IdTCPIP: - ErrMsg[0] = 0; - switch (HIWORD(lParam)) { - case WSAECONNREFUSED: - get_lang_msg("MSG_COMM_REFUSE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection refused", ts->UILanguageFile); - _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg); - break; - case WSAENETUNREACH: - get_lang_msg("MSG_COMM_REACH_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Network cannot be reached", ts->UILanguageFile); - _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg); - break; - case WSAETIMEDOUT: - get_lang_msg("MSG_COMM_CONNECT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection timed out", ts->UILanguageFile); - _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg); - break; - default: - get_lang_msg("MSG_COMM_TIMEOUT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot connect the host", ts->UILanguageFile); - _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg); - } - if (HIWORD(lParam)>0) { -#ifndef NO_INET6 - /* connect() failed */ - if (cv->res->ai_next != NULL) { - /* try to connect with other protocol */ - CloseSocket(cv->s); - for (cv->res = cv->res->ai_next; cv->res; cv->res = cv->res->ai_next) { - cv->s = OpenSocket(cv); - if (cv->s == INVALID_SOCKET) { - CloseSocket(cv->s); - continue; - } - AsyncConnect(cv); - cv->Ready = FALSE; - cv->RetryWithOtherProtocol = TRUE; /* retry with other procotol */ - return; - } - } else { - /* trying with all protocol family are failed */ - if (cv->NoMsg==0) - { - get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); - MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); - } - PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); - cv->RetryWithOtherProtocol = FALSE; - return; - } -#else - if (cv->NoMsg==0) - MessageBox(cv->HWin,ErrMsg,ErrorCaption, - MB_TASKMODAL | MB_ICONEXCLAMATION); - PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); - return; -#endif /* NO_INET6 */ - } - -#ifndef NO_INET6 - /* here is connection established */ - cv->RetryWithOtherProtocol = FALSE; -#endif /* NO_INET6 */ - PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_READ | FD_OOB | FD_CLOSE); - TCPIPClosed = FALSE; - break; - - case IdSerial: - _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort); - ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp); - _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort); - memset(&wol,0,sizeof(OVERLAPPED)); - wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp); - _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort); - memset(&rol,0,sizeof(OVERLAPPED)); - rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp); - - /* create the receiver thread */ - if (_beginthread(CommThread,0,cv) == -1) { - get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); - get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile); - MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); - } - break; - - case IdFile: - cv->RRQ = TRUE; - break; - } - cv->Ready = TRUE; -} - -BOOL CommCanClose(PComVar cv) -{ // check if data remains in buffer - if (! cv->Open) { - return TRUE; - } - if (cv->InBuffCount>0) { - return FALSE; - } - if ((cv->HLogBuf!=NULL) && - ((cv->LCount>0) || - (cv->DCount>0))) { - return FALSE; - } - if ((cv->HBinBuf!=NULL) && - (cv->BCount>0)) { - return FALSE; - } - return TRUE; -} - -void CommClose(PComVar cv) -{ - if ( ! cv->Open ) { - return; - } - cv->Open = FALSE; - - /* disable event message posting & flush buffer */ - cv->RRQ = FALSE; - cv->Ready = FALSE; - cv->InPtr = 0; - cv->InBuffCount = 0; - cv->OutPtr = 0; - cv->OutBuffCount = 0; - cv->LineModeBuffCount = 0; - cv->FlushLen = 0; - cv->Flush = FALSE; - - /* close port & release resources */ - switch (cv->PortType) { - case IdTCPIP: - if (HAsync!=0) { - PWSACancelAsyncRequest(HAsync); - } - HAsync = 0; -#ifndef NO_INET6 - freeaddrinfo(cv->res0); -#endif /* NO_INET6 */ - if ( cv->s!=INVALID_SOCKET ) { - Pclosesocket(cv->s); - } - cv->s = INVALID_SOCKET; - TTXCloseTCP(); /* TTPLUG */ - FreeWinsock(); - break; - case IdSerial: - if ( cv->ComID != INVALID_HANDLE_VALUE ) { - CloseHandle(ReadEnd); - CloseHandle(wol.hEvent); - CloseHandle(rol.hEvent); - PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT | - PURGE_TXCLEAR | PURGE_RXCLEAR); - EscapeCommFunction(cv->ComID,CLRDTR); - SetCommMask(cv->ComID,0); - PCloseFile(cv->ComID); - ClearCOMFlag(cv->ComPort); - } - TTXCloseFile(); /* TTPLUG */ - break; - case IdFile: - if (cv->ComID != INVALID_HANDLE_VALUE) { - PCloseFile(cv->ComID); - } - TTXCloseFile(); /* TTPLUG */ - break; - } - cv->ComID = INVALID_HANDLE_VALUE; - cv->PortType = 0; -} - -void CommProcRRQ(PComVar cv) -{ - if ( ! cv->Ready ) { - return; - } - /* disable receive request */ - switch (cv->PortType) { - case IdTCPIP: - if (! TCPIPClosed) { - PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_OOB | FD_CLOSE); - } - break; - case IdSerial: - break; - } - cv->RRQ = TRUE; - CommReceive(cv); -} - -void CommReceive(PComVar cv) -{ - DWORD C; - DWORD DErr; - - if (! cv->Ready || ! cv->RRQ || - (cv->InBuffCount>=InBuffSize)) { - return; - } - - /* Compact buffer */ - if ((cv->InBuffCount>0) && (cv->InPtr>0)) { - memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount); - cv->InPtr = 0; - } - - if (cv->InBuffCount<InBuffSize) { - switch (cv->PortType) { - case IdTCPIP: - C = Precv(cv->s, &(cv->InBuff[cv->InBuffCount]), - InBuffSize-cv->InBuffCount, 0); - if (C == SOCKET_ERROR) { - C = 0; - PWSAGetLastError(); - } - cv->InBuffCount = cv->InBuffCount + C; - break; - case IdSerial: - do { - ClearCommError(cv->ComID,&DErr,NULL); - if (! PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]), - InBuffSize-cv->InBuffCount,&C,&rol)) { - if (GetLastError() == ERROR_IO_PENDING) { - if (WaitForSingleObject(rol.hEvent, 1000) != WAIT_OBJECT_0) { - C = 0; - } - else { - GetOverlappedResult(cv->ComID,&rol,&C,FALSE); - } - } - else { - C = 0; - } - } - cv->InBuffCount = cv->InBuffCount + C; - } while ((C!=0) && (cv->InBuffCount<InBuffSize)); - ClearCommError(cv->ComID,&DErr,NULL); - break; - case IdFile: - if (PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]), - InBuffSize-cv->InBuffCount,&C,NULL)) { - if (C == 0) { - DErr = ERROR_HANDLE_EOF; - } - else { - cv->InBuffCount = cv->InBuffCount + C; - } - } - else { - DErr = GetLastError(); - } - break; - } - } - - if (cv->InBuffCount==0) { - switch (cv->PortType) { - case IdTCPIP: - if (! TCPIPClosed) { - PWSAAsyncSelect(cv->s,cv->HWin, WM_USER_COMMNOTIFY, - FD_READ | FD_OOB | FD_CLOSE); - } - break; - case IdSerial: - cv->RRQ = FALSE; - SetEvent(ReadEnd); - return; - case IdFile: - if (DErr != ERROR_IO_PENDING) { - PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); - cv->RRQ = FALSE; - } - else { - cv->RRQ = TRUE; - } - return; - } - cv->RRQ = FALSE; - } -} - -void CommSend(PComVar cv) -{ - int delay; - COMSTAT Stat; - BYTE LineEnd; - int C, D, Max; - DWORD DErr; - - if ((! cv->Open) || (! cv->Ready)) { - cv->OutBuffCount = 0; - return; - } - - if ((cv->OutBuffCount == 0) || (! cv->CanSend)) { - return; - } - - /* Max num of bytes to be written */ - switch (cv->PortType) { - case IdTCPIP: - if (TCPIPClosed) { - cv->OutBuffCount = 0; - } - Max = cv->OutBuffCount; - break; - case IdSerial: - ClearCommError(cv->ComID,&DErr,&Stat); - Max = OutBuffSize - Stat.cbOutQue; - break; - case IdFile: - Max = cv->OutBuffCount; - break; - } - - if ( Max<=0 ) { - return; - } - if ( Max > cv->OutBuffCount ) { - Max = cv->OutBuffCount; - } - - if (cv->PortType == IdTCPIP && cv->TelFlag) { - cv->LastSendTime = time(NULL); - } - - C = Max; - delay = 0; - - if ( cv->DelayFlag && (cv->PortType==IdSerial) ) { - if ( cv->DelayPerLine > 0 ) { - if ( cv->CRSend==IdCR ) { - LineEnd = 0x0d; - } - else { - LineEnd = 0x0a; - } - C = 1; - if ( cv->DelayPerChar==0 ) { - while ((C<Max) && (cv->OutBuff[cv->OutPtr+C-1]!=LineEnd)) { - C++; - } - } - if ( cv->OutBuff[cv->OutPtr+C-1]==LineEnd ) { - delay = cv->DelayPerLine; - } - else { - delay = cv->DelayPerChar; - } - } - else if ( cv->DelayPerChar > 0 ) { - C = 1; - delay = cv->DelayPerChar; - } - } - - /* Write to comm driver/Winsock */ - switch (cv->PortType) { - case IdTCPIP: - D = Psend(cv->s, &(cv->OutBuff[cv->OutPtr]), C, 0); - if ( D==SOCKET_ERROR ) { /* if error occurs */ - PWSAGetLastError(); /* Clear error */ - D = 0; - } - break; - - case IdSerial: - if (! PWriteFile(cv->ComID,&(cv->OutBuff[cv->OutPtr]),C,(LPDWORD)&D,&wol)) { - if (GetLastError() == ERROR_IO_PENDING) { - if (WaitForSingleObject(wol.hEvent,1000) != WAIT_OBJECT_0) { - D = C; /* Time out, ignore data */ - } - else { - GetOverlappedResult(cv->ComID,&wol,(LPDWORD)&D,FALSE); - } - } - else { /* I/O error */ - D = C; /* ignore error */ - } - } - ClearCommError(cv->ComID,&DErr,&Stat); - break; - - case IdFile: - if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) { - if (! GetLastError() == ERROR_IO_PENDING) { - D = C; /* ignore data */ - } - } - break; - } - - cv->OutBuffCount = cv->OutBuffCount - D; - if ( cv->OutBuffCount==0 ) { - cv->OutPtr = 0; - } - else { - cv->OutPtr = cv->OutPtr + D; - } - - if ( (C==D) && (delay>0) ) { - cv->CanSend = FALSE; - SetTimer(cv->HWin, IdDelayTimer, delay, NULL); - } -} - -void CommSendBreak(PComVar cv) -/* for only serial ports */ -{ - MSG DummyMsg; - - if ( ! cv->Ready ) { - return; - } - - switch (cv->PortType) { - case IdSerial: - /* Set com port into a break state */ - SetCommBreak(cv->ComID); - - /* pause for 1 sec */ - if (SetTimer(cv->HWin, IdBreakTimer, 1000, NULL) != 0) { - GetMessage(&DummyMsg,cv->HWin,WM_TIMER,WM_TIMER); - } - - /* Set com port into the nonbreak state */ - ClearCommBreak(cv->ComID); - break; - } -} - -void CommLock(PTTSet ts, PComVar cv, BOOL Lock) -{ - BYTE b; - DWORD Func; - - if (! cv->Ready) { - return; - } - if ((cv->PortType==IdTCPIP) || - (cv->PortType==IdSerial) && - (ts->Flow!=IdFlowHard)) { - if (Lock) { - b = XOFF; - } - else { - b = XON; - } - CommBinaryOut(cv,&b,1); - } - else if ((cv->PortType==IdSerial) && - (ts->Flow==IdFlowHard)) { - if (Lock) { - Func = CLRRTS; - } - else { - Func = SETRTS; - } - EscapeCommFunction(cv->ComID,Func); - } -} - -int GetCommSerialBaudRate(int id) -{ - char *ch; - int val; - - // id-1ªXgÌindexÆÈéB - ch = BaudList[id - 1]; - val = atoi(ch); - return (val); -} - -BOOL PrnOpen(PCHAR DevName) -{ - char Temp[MAXPATHLEN]; - DCB dcb; - DWORD DErr; - COMMTIMEOUTS ctmo; - - strncpy_s(Temp, sizeof(Temp),DevName, _TRUNCATE); - Temp[4] = 0; // COMn or LPTn - LPTFlag = (Temp[0]=='L') || - (Temp[0]=='l'); - PrnID = CreateFile(Temp,GENERIC_WRITE, - 0,NULL,OPEN_EXISTING, - 0,NULL); - if (PrnID == INVALID_HANDLE_VALUE) { - return FALSE; - } - - if (GetCommState(PrnID,&dcb)) { - BuildCommDCB(DevName,&dcb); - SetCommState(PrnID,&dcb); - } - ClearCommError(PrnID,&DErr,NULL); - if (! LPTFlag) { - SetupComm(PrnID,0,CommOutQueSize); - } - /* flush output buffer */ - PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR); - memset(&ctmo,0,sizeof(ctmo)); - ctmo.WriteTotalTimeoutConstant = 1000; - SetCommTimeouts(PrnID,&ctmo); - if (! LPTFlag) { - EscapeCommFunction(PrnID,SETDTR); - } - return TRUE; -} - -int PrnWrite(PCHAR b, int c) -{ - int d; - DWORD DErr; - COMSTAT Stat; - - if (PrnID == INVALID_HANDLE_VALUE ) { - return c; - } - - ClearCommError(PrnID,&DErr,&Stat); - if (! LPTFlag && - (OutBuffSize - (int)Stat.cbOutQue < c)) { - c = OutBuffSize - Stat.cbOutQue; - } - if (c<=0) { - return 0; - } - if (! WriteFile(PrnID,b,c,(LPDWORD)&d,NULL)) { - d = 0; - } - ClearCommError(PrnID,&DErr,NULL); - return d; -} - -void PrnCancel() -{ - PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR); - PrnClose(); -} - -void PrnClose() -{ - if (PrnID != INVALID_HANDLE_VALUE) { - if (!LPTFlag) { - EscapeCommFunction(PrnID,CLRDTR); - } - CloseHandle(PrnID); - } - PrnID = INVALID_HANDLE_VALUE; -} +/* Tera Term + Copyright(C) 1994-1998 T. Teranishi + All rights reserved. */ +/* IPv6 modification is Copyright (C) 2000, 2001 Jun-ya KATO <kato****@win6*****> */ + +/* TERATERM.EXE, Communication routines */ +#include "teraterm.h" +#include "tttypes.h" +#include "tt_res.h" +#include <process.h> + +#include "ttcommon.h" +#include "ttwsk.h" +#include "ttlib.h" +#include "ttfileio.h" +#include "ttplug.h" /* TTPLUG */ + +#include "commlib.h" +#ifndef NO_INET6 +#include <winsock2.h> +#include <ws2tcpip.h> +#include <stdio.h> /* for _snprintf() */ +#include "WSAAsyncGetAddrInfo.h" +#endif /* NO_INET6 */ +#include <time.h> + +static SOCKET OpenSocket(PComVar); +static void AsyncConnect(PComVar); +static int CloseSocket(SOCKET); + +/* create socket */ +static SOCKET OpenSocket(PComVar cv) +{ + cv->s = cv->res->ai_family; + cv->s = Psocket(cv->res->ai_family, cv->res->ai_socktype, cv->res->ai_protocol); + return cv->s; +} + +/* connect with asynchronous mode */ +static void AsyncConnect(PComVar cv) +{ + int Err; + BOOL BBuf; + BBuf = TRUE; + /* set synchronous mode */ + PWSAAsyncSelect(cv->s,cv->HWin,0,0); + Psetsockopt(cv->s,(int)SOL_SOCKET,SO_OOBINLINE,(char FAR *)&BBuf,sizeof(BBuf)); + /* set asynchronous mode */ + PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMOPEN, FD_CONNECT); + + // zXgÖÌÚ±ÉêèÔ§ÂÆA§IÉ\PbgðN[YµÄA + // Ú±ðLZ³¹éBlª0ÌêͽàµÈ¢B + // (2007.1.11 yutaka) + if (*cv->ConnetingTimeout > 0) { + SetTimer(cv->HWin, IdCancelConnectTimer, *cv->ConnetingTimeout * 1000, NULL); + } + + /* WM_USER_COMMOPEN occurs, CommOpen is called, then CommStart is called */ + Err = Pconnect(cv->s, cv->res->ai_addr, cv->res->ai_addrlen); + if (Err != 0) { + Err = PWSAGetLastError(); + if (Err == WSAEWOULDBLOCK) { + /* Do nothing */ + } else if (Err!=0 ) { + PostMessage(cv->HWin, WM_USER_COMMOPEN,0, + MAKELONG(FD_CONNECT,Err)); + } + } +} + +/* close socket */ +static int CloseSocket(SOCKET s) +{ + return Pclosesocket(s); +} + +#define CommInQueSize 8192 +#define CommOutQueSize 2048 +#define CommXonLim 2048 +#define CommXoffLim 2048 + +#define READENDNAME "ReadEnd" +#define WRITENAME "Write" +#define READNAME "Read" +#define PRNWRITENAME "PrnWrite" + +static HANDLE ReadEnd; +static OVERLAPPED wol, rol; + +// Winsock async operation handle +static HANDLE HAsync=0; + +BOOL TCPIPClosed = TRUE; + +/* Printer port handle for + direct pass-thru printing */ +static HANDLE PrnID = INVALID_HANDLE_VALUE; +static BOOL LPTFlag; + +// Initialize ComVar. +// This routine is called only once +// by the initialization procedure of Tera Term. +void CommInit(PComVar cv) +{ + cv->Open = FALSE; + cv->Ready = FALSE; + +// log-buffer variables + cv->HLogBuf = 0; + cv->HBinBuf = 0; + cv->LogBuf = NULL; + cv->BinBuf = NULL; + cv->LogPtr = 0; + cv->LStart = 0; + cv->LCount = 0; + cv->BinPtr = 0; + cv->BStart = 0; + cv->BCount = 0; + cv->DStart = 0; + cv->DCount = 0; + cv->BinSkip = 0; + cv->FilePause = 0; + cv->ProtoFlag = FALSE; +/* message flag */ + cv->NoMsg = 0; +} + +/* reset a serial port which is already open */ +void CommResetSerial(PTTSet ts, PComVar cv, BOOL ClearBuff) +{ + DCB dcb; + DWORD DErr; + COMMTIMEOUTS ctmo; + + if (! cv->Open || + (cv->PortType != IdSerial)) { + return; + } + + ClearCommError(cv->ComID,&DErr,NULL); + SetupComm(cv->ComID,CommInQueSize,CommOutQueSize); + /* flush input and output buffers */ + if (ClearBuff) { + PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT | + PURGE_TXCLEAR | PURGE_RXCLEAR); + } + + memset(&ctmo,0,sizeof(ctmo)); + ctmo.ReadIntervalTimeout = MAXDWORD; + ctmo.WriteTotalTimeoutConstant = 500; + SetCommTimeouts(cv->ComID,&ctmo); + cv->InBuffCount = 0; + cv->InPtr = 0; + cv->OutBuffCount = 0; + cv->OutPtr = 0; + + cv->DelayPerChar = ts->DelayPerChar; + cv->DelayPerLine = ts->DelayPerLine; + + memset(&dcb,0,sizeof(DCB)); + dcb.DCBlength = sizeof(DCB); + dcb.BaudRate = GetCommSerialBaudRate(ts->Baud); + dcb.fBinary = TRUE; + switch (ts->Parity) { + case IdParityEven: + dcb.fParity = TRUE; + dcb.Parity = EVENPARITY; + break; + case IdParityOdd: + dcb.fParity = TRUE; + dcb.Parity = ODDPARITY; + break; + case IdParityNone: + dcb.Parity = NOPARITY; + break; + } + + dcb.fDtrControl = DTR_CONTROL_ENABLE; + dcb.fRtsControl = RTS_CONTROL_ENABLE; + switch (ts->Flow) { + case IdFlowX: + dcb.fOutX = TRUE; + dcb.fInX = TRUE; + dcb.XonLim = CommXonLim; + dcb.XoffLim = CommXoffLim; + dcb.XonChar = XON; + dcb.XoffChar = XOFF; + break; + case IdFlowHard: + dcb.fOutxCtsFlow = TRUE; + dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; + break; + } + + switch (ts->DataBit) { + case IdDataBit7: + dcb.ByteSize = 7; + break; + case IdDataBit8: + dcb.ByteSize = 8; + break; + } + switch (ts->StopBit) { + case IdStopBit1: + dcb.StopBits = ONESTOPBIT; + break; + case IdStopBit2: + dcb.StopBits = TWOSTOPBITS; + break; + } + + SetCommState(cv->ComID, &dcb); + + /* enable receive request */ + SetCommMask(cv->ComID,0); + SetCommMask(cv->ComID,EV_RXCHAR); +} + +void CommOpen(HWND HW, PTTSet ts, PComVar cv) +{ +#ifdef NO_INET6 + int Err; +#endif /* NO_INET6 */ + char ErrMsg[21]; + char P[50]; + + MSG Msg; +#ifndef NO_INET6 + ADDRINFO hints; + char pname[NI_MAXSERV]; +#else + char HEntBuff[MAXGETHOSTSTRUCT]; + u_long addr; + SOCKADDR_IN saddr; +#endif /* NO_INET6 */ + + BOOL InvalidHost; +#ifdef NO_INET6 + BOOL BBuf; +#endif /* NO_INET6 */ + + char uimsg[MAX_UIMSG]; + + /* initialize ComVar */ + cv->InBuffCount = 0; + cv->InPtr = 0; + cv->OutBuffCount = 0; + cv->OutPtr = 0; + cv->HWin = HW; + cv->Ready = FALSE; + cv->Open = FALSE; + cv->PortType = ts->PortType; + cv->ComPort = 0; + cv->RetryCount = 0; +#ifndef NO_INET6 + cv->RetryWithOtherProtocol = TRUE; +#endif /* NO_INET6 */ + cv->s = INVALID_SOCKET; + cv->ComID = INVALID_HANDLE_VALUE; + cv->CanSend = TRUE; + cv->RRQ = FALSE; + cv->SendKanjiFlag = FALSE; + cv->SendCode = IdASCII; + cv->EchoKanjiFlag = FALSE; + cv->EchoCode = IdASCII; + cv->Language = ts->Language; + cv->CRSend = ts->CRSend; + cv->KanjiCodeEcho = ts->KanjiCode; + cv->JIS7KatakanaEcho = ts->JIS7Katakana; + cv->KanjiCodeSend = ts->KanjiCodeSend; + cv->JIS7KatakanaSend = ts->JIS7KatakanaSend; + cv->KanjiIn = ts->KanjiIn; + cv->KanjiOut = ts->KanjiOut; + cv->RussHost = ts->RussHost; + cv->RussClient = ts->RussClient; + cv->DelayFlag = TRUE; + cv->DelayPerChar = ts->DelayPerChar; + cv->DelayPerLine = ts->DelayPerLine; + cv->TelBinRecv = FALSE; + cv->TelBinSend = FALSE; + cv->TelFlag = FALSE; + cv->TelMode = FALSE; + cv->IACFlag = FALSE; + cv->TelCRFlag = FALSE; + cv->TelCRSend = FALSE; + cv->TelCRSendEcho = FALSE; + cv->TelAutoDetect = ts->TelAutoDetect; /* TTPLUG */ + cv->Locale = ts->Locale; + cv->CodePage = &ts->CodePage; + cv->ConnetingTimeout = &ts->ConnectingTimeout; + cv->LastSendTime = time(NULL); + cv->LineModeBuffCount = 0; + cv->Flush = FALSE; + cv->FlushLen = 0; + cv->TelLineMode = FALSE; + + if ((ts->PortType!=IdSerial) && (strlen(ts->HostName)==0)) + { + PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); + return; + } + + switch (ts->PortType) { + case IdTCPIP: + cv->TelFlag = (ts->Telnet > 0); + if (ts->EnableLineMode) { + cv->TelLineMode = TRUE; + } + if (! LoadWinsock()) { + if (cv->NoMsg==0) { + get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); + get_lang_msg("MSG_WINSOCK_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot use winsock", ts->UILanguageFile); + MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); + } + InvalidHost = TRUE; + } + else { + TTXOpenTCP(); /* TTPLUG */ + cv->Open = TRUE; +#ifndef NO_INET6 + /* resolving address */ + memset(&hints, 0, sizeof(hints)); + hints.ai_family = ts->ProtocolFamily; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + _snprintf_s(pname, sizeof(pname), _TRUNCATE, "%d", ts->TCPPort); + + HAsync = WSAAsyncGetAddrInfo(HW, WM_USER_GETHOST, + ts->HostName, pname, &hints, &cv->res0); + if (HAsync == 0) + InvalidHost = TRUE; + else { + cv->ComPort = 1; // set "getting host" flag + // (see CVTWindow::OnSysCommand()) + do { + if (GetMessage(&Msg,0,0,0)) { + if ((Msg.hwnd==HW) && + ((Msg.message == WM_SYSCOMMAND) && + ((Msg.wParam & 0xfff0) == SC_CLOSE) || + (Msg.message == WM_COMMAND) && + (LOWORD(Msg.wParam) == ID_FILE_EXIT) || + (Msg.message == WM_CLOSE))) { /* Exit when the user closes Tera Term */ + PWSACancelAsyncRequest(HAsync); + CloseHandle(HAsync); + HAsync = 0; + cv->ComPort = 0; // clear "getting host" flag + PostMessage(HW,Msg.message,Msg.wParam,Msg.lParam); + return; + } + if (Msg.message != WM_USER_GETHOST) { /* Prosess messages */ + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + } + else { + return; + } + } while (Msg.message!=WM_USER_GETHOST); + cv->ComPort = 0; // clear "getting host" flag + CloseHandle(HAsync); + HAsync = 0; + InvalidHost = WSAGETASYNCERROR(Msg.lParam) != 0; + } + } /* if (!LoadWinsock()) */ + + if (InvalidHost) { + if (cv->NoMsg==0) { + get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); + get_lang_msg("MSG_INVALID_HOST_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Invalid host", ts->UILanguageFile); + MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); + } + goto BreakSC; + } + for (cv->res = cv->res0; cv->res; cv->res = cv->res->ai_next) { + cv->s = OpenSocket(cv); + if (cv->s == INVALID_SOCKET) { + CloseSocket(cv->s); + continue; + } + /* start asynchronous connect */ + AsyncConnect(cv); + break; /* break for-loop immediately */ + } + break; +#else + if ((ts->HostName[0] >= 0x30) && (ts->HostName[0] <= 0x39)) + { + addr = Pinet_addr(ts->HostName); + InvalidHost = (addr == 0xffffffff); + } + else { + HAsync = PWSAAsyncGetHostByName(HW,WM_USER_GETHOST, + ts->HostName,HEntBuff,sizeof(HEntBuff)); + if (HAsync == 0) + InvalidHost = TRUE; + else { + cv->ComPort = 1; // set "getting host" flag + // (see CVTWindow::OnSysCommand()) + do { + if (GetMessage(&Msg,0,0,0)) + { + if ((Msg.hwnd==HW) && + ((Msg.message == WM_SYSCOMMAND) && + ((Msg.wParam & 0xfff0) == SC_CLOSE) || + (Msg.message == WM_COMMAND) && + (LOWORD(Msg.wParam) == ID_FILE_EXIT) || + (Msg.message == WM_CLOSE))) + { /* Exit when the user closes Tera Term */ + PWSACancelAsyncRequest(HAsync); + HAsync = 0; + cv->ComPort = 0; // clear "getting host" flag + PostMessage(HW,Msg.message,Msg.wParam,Msg.lParam); + return; + } + if (Msg.message != WM_USER_GETHOST) + { /* Prosess messages */ + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + } + else { + return; + } + } while (Msg.message!=WM_USER_GETHOST); + cv->ComPort = 0; // clear "getting host" flag + HAsync = 0; + InvalidHost = WSAGETASYNCERROR(Msg.lParam) != 0; + if (! InvalidHost) + { + if (((PHOSTENT)HEntBuff)->h_addr_list != NULL) + memcpy(&addr, + ((PHOSTENT)HEntBuff)->h_addr_list[0],sizeof(addr)); + else + InvalidHost = TRUE; + } + } + + } + + if (InvalidHost) + { + if (cv->NoMsg==0) + MessageBox(cv->HWin,"Invalid host",ErrorCaption, + MB_TASKMODAL | MB_ICONEXCLAMATION); + } + else { + cv->s= Psocket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + if (cv->s==INVALID_SOCKET) + { + InvalidHost = TRUE; + if (cv->NoMsg==0) + MessageBox(cv->HWin,ErrorCantConn,ErrorCaption, + MB_TASKMODAL | MB_ICONEXCLAMATION); + } + else { + BBuf = TRUE; + Psetsockopt(cv->s,(int)SOL_SOCKET,SO_OOBINLINE,(char FAR *)&BBuf,sizeof(BBuf)); + + PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMOPEN, FD_CONNECT); + saddr.sin_family = AF_INET; + saddr.sin_port = Phtons(ts->TCPPort); + saddr.sin_addr.s_addr = addr; + memset(saddr.sin_zero,0,8); + + Err = Pconnect(cv->s,(LPSOCKADDR)&saddr,sizeof(saddr)); + if (Err!=0 ) Err = PWSAGetLastError(); + if (Err==WSAEWOULDBLOCK ) + { + /* Do nothing */ + } + else if (Err!=0 ) + PostMessage(cv->HWin, WM_USER_COMMOPEN,0, + MAKELONG(FD_CONNECT,Err)); + } + } + } + break; +#endif /* NO_INET6 */ + + case IdSerial: + InitFileIO(IdSerial); /* TTPLUG */ + TTXOpenFile(); /* TTPLUG */ + _snprintf_s(P, sizeof(P), _TRUNCATE, "COM%d", ts->ComPort); + strncpy_s(ErrMsg, sizeof(ErrMsg),P, _TRUNCATE); + strncpy_s(P, sizeof(P),"\\\\.\\", _TRUNCATE); + strncat_s(P, sizeof(P),ErrMsg, _TRUNCATE); + cv->ComID = + PCreateFile(P,GENERIC_READ | GENERIC_WRITE, + 0,NULL,OPEN_EXISTING, + FILE_FLAG_OVERLAPPED,NULL); + if (cv->ComID == INVALID_HANDLE_VALUE ) { + get_lang_msg("MSG_CANTOEPN_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open %s", ts->UILanguageFile); + _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, ts->UIMsg, &P[4]); + + if (cv->NoMsg==0) { + get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); + MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); + } + InvalidHost = TRUE; + } + else { + cv->Open = TRUE; + cv->ComPort = ts->ComPort; + CommResetSerial(ts, cv, ts->ClearComBuffOnOpen); + if (!ts->ClearComBuffOnOpen) { + cv->RRQ = TRUE; + } + + /* notify to VT window that Comm Port is open */ + PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0); + InvalidHost = FALSE; + + SetCOMFlag(ts->ComPort); + } + break; /* end of "case IdSerial:" */ + + case IdFile: + InitFileIO(IdFile); /* TTPLUG */ + TTXOpenFile(); /* TTPLUG */ + cv->ComID = PCreateFile(ts->HostName,GENERIC_READ,0,NULL, + OPEN_EXISTING,0,NULL); + InvalidHost = (cv->ComID == INVALID_HANDLE_VALUE); + if (InvalidHost) { + if (cv->NoMsg==0) { + get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); + get_lang_msg("MSG_CANTOEPN_FILE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot open file", ts->UILanguageFile); + MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); + } + } + else { + cv->Open = TRUE; + PostMessage(cv->HWin, WM_USER_COMMOPEN, 0, 0); + } + break; + } /* end of "switch" */ + +#ifndef NO_INET6 +BreakSC: +#endif /* NO_INET6 */ + if (InvalidHost) { + PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); + if ( (ts->PortType==IdTCPIP) && cv->Open ) { + if ( cv->s!=INVALID_SOCKET ) { + Pclosesocket(cv->s); + } + FreeWinsock(); + } + return; + } +} + +void CommThread(void *arg) +{ + DWORD Evt; + PComVar cv = (PComVar)arg; + DWORD DErr; + HANDLE REnd; + char Temp[20]; + + _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort); + REnd = OpenEvent(EVENT_ALL_ACCESS,FALSE, Temp); + while (TRUE) { + if (WaitCommEvent(cv->ComID,&Evt,NULL)) { + if (! cv->Ready) { + _endthread(); + } + if (! cv->RRQ) { + PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_READ); + } + WaitForSingleObject(REnd,INFINITE); + } + else { + DErr = GetLastError(); // this returns 995 (operation aborted) if a USB com port is removed + if (! cv->Ready || ERROR_OPERATION_ABORTED == DErr) { + _endthread(); + } + ClearCommError(cv->ComID,&DErr,NULL); + } + } +} + +void CommStart(PComVar cv, LONG lParam, PTTSet ts) +{ + char ErrMsg[31]; + char Temp[20]; + char uimsg[MAX_UIMSG]; + + if (! cv->Open ) { + return; + } + if ( cv->Ready ) { + return; + } + + // LZ^C}ª êÎæèÁ·B½¾µA±Ì_Å WM_TIMER ªçêÄ¢éÂ\«Í éB + if (*cv->ConnetingTimeout > 0) { + KillTimer(cv->HWin, IdCancelConnectTimer); + } + + switch (cv->PortType) { + case IdTCPIP: + ErrMsg[0] = 0; + switch (HIWORD(lParam)) { + case WSAECONNREFUSED: + get_lang_msg("MSG_COMM_REFUSE_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection refused", ts->UILanguageFile); + _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg); + break; + case WSAENETUNREACH: + get_lang_msg("MSG_COMM_REACH_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Network cannot be reached", ts->UILanguageFile); + _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg); + break; + case WSAETIMEDOUT: + get_lang_msg("MSG_COMM_CONNECT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Connection timed out", ts->UILanguageFile); + _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg); + break; + default: + get_lang_msg("MSG_COMM_TIMEOUT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Cannot connect the host", ts->UILanguageFile); + _snprintf_s(ErrMsg, sizeof(ErrMsg), _TRUNCATE, "%s", ts->UIMsg); + } + if (HIWORD(lParam)>0) { +#ifndef NO_INET6 + /* connect() failed */ + if (cv->res->ai_next != NULL) { + /* try to connect with other protocol */ + CloseSocket(cv->s); + for (cv->res = cv->res->ai_next; cv->res; cv->res = cv->res->ai_next) { + cv->s = OpenSocket(cv); + if (cv->s == INVALID_SOCKET) { + CloseSocket(cv->s); + continue; + } + AsyncConnect(cv); + cv->Ready = FALSE; + cv->RetryWithOtherProtocol = TRUE; /* retry with other procotol */ + return; + } + } else { + /* trying with all protocol family are failed */ + if (cv->NoMsg==0) + { + get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); + MessageBox(cv->HWin,ErrMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); + } + PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); + cv->RetryWithOtherProtocol = FALSE; + return; + } +#else + if (cv->NoMsg==0) + MessageBox(cv->HWin,ErrMsg,ErrorCaption, + MB_TASKMODAL | MB_ICONEXCLAMATION); + PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); + return; +#endif /* NO_INET6 */ + } + +#ifndef NO_INET6 + /* here is connection established */ + cv->RetryWithOtherProtocol = FALSE; +#endif /* NO_INET6 */ + PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_READ | FD_OOB | FD_CLOSE); + TCPIPClosed = FALSE; + break; + + case IdSerial: + _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READENDNAME, cv->ComPort); + ReadEnd = CreateEvent(NULL,FALSE,FALSE,Temp); + _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", WRITENAME, cv->ComPort); + memset(&wol,0,sizeof(OVERLAPPED)); + wol.hEvent = CreateEvent(NULL,TRUE,TRUE,Temp); + _snprintf_s(Temp, sizeof(Temp), _TRUNCATE, "%s%d", READNAME, cv->ComPort); + memset(&rol,0,sizeof(OVERLAPPED)); + rol.hEvent = CreateEvent(NULL,TRUE,FALSE,Temp); + + /* create the receiver thread */ + if (_beginthread(CommThread,0,cv) == -1) { + get_lang_msg("MSG_TT_ERROR", uimsg, sizeof(uimsg), "Tera Term: Error", ts->UILanguageFile); + get_lang_msg("MSG_TT_ERROR", ts->UIMsg, sizeof(ts->UIMsg), "Can't create thread", ts->UILanguageFile); + MessageBox(cv->HWin,ts->UIMsg,uimsg,MB_TASKMODAL | MB_ICONEXCLAMATION); + } + break; + + case IdFile: + cv->RRQ = TRUE; + break; + } + cv->Ready = TRUE; +} + +BOOL CommCanClose(PComVar cv) +{ // check if data remains in buffer + if (! cv->Open) { + return TRUE; + } + if (cv->InBuffCount>0) { + return FALSE; + } + if ((cv->HLogBuf!=NULL) && + ((cv->LCount>0) || + (cv->DCount>0))) { + return FALSE; + } + if ((cv->HBinBuf!=NULL) && + (cv->BCount>0)) { + return FALSE; + } + return TRUE; +} + +void CommClose(PComVar cv) +{ + if ( ! cv->Open ) { + return; + } + cv->Open = FALSE; + + /* disable event message posting & flush buffer */ + cv->RRQ = FALSE; + cv->Ready = FALSE; + cv->InPtr = 0; + cv->InBuffCount = 0; + cv->OutPtr = 0; + cv->OutBuffCount = 0; + cv->LineModeBuffCount = 0; + cv->FlushLen = 0; + cv->Flush = FALSE; + + /* close port & release resources */ + switch (cv->PortType) { + case IdTCPIP: + if (HAsync!=0) { + PWSACancelAsyncRequest(HAsync); + } + HAsync = 0; +#ifndef NO_INET6 + freeaddrinfo(cv->res0); +#endif /* NO_INET6 */ + if ( cv->s!=INVALID_SOCKET ) { + Pclosesocket(cv->s); + } + cv->s = INVALID_SOCKET; + TTXCloseTCP(); /* TTPLUG */ + FreeWinsock(); + break; + case IdSerial: + if ( cv->ComID != INVALID_HANDLE_VALUE ) { + CloseHandle(ReadEnd); + CloseHandle(wol.hEvent); + CloseHandle(rol.hEvent); + PurgeComm(cv->ComID, PURGE_TXABORT | PURGE_RXABORT | + PURGE_TXCLEAR | PURGE_RXCLEAR); + EscapeCommFunction(cv->ComID,CLRDTR); + SetCommMask(cv->ComID,0); + PCloseFile(cv->ComID); + ClearCOMFlag(cv->ComPort); + } + TTXCloseFile(); /* TTPLUG */ + break; + case IdFile: + if (cv->ComID != INVALID_HANDLE_VALUE) { + PCloseFile(cv->ComID); + } + TTXCloseFile(); /* TTPLUG */ + break; + } + cv->ComID = INVALID_HANDLE_VALUE; + cv->PortType = 0; +} + +void CommProcRRQ(PComVar cv) +{ + if ( ! cv->Ready ) { + return; + } + /* disable receive request */ + switch (cv->PortType) { + case IdTCPIP: + if (! TCPIPClosed) { + PWSAAsyncSelect(cv->s,cv->HWin,WM_USER_COMMNOTIFY, FD_OOB | FD_CLOSE); + } + break; + case IdSerial: + break; + } + cv->RRQ = TRUE; + CommReceive(cv); +} + +void CommReceive(PComVar cv) +{ + DWORD C; + DWORD DErr; + + if (! cv->Ready || ! cv->RRQ || + (cv->InBuffCount>=InBuffSize)) { + return; + } + + /* Compact buffer */ + if ((cv->InBuffCount>0) && (cv->InPtr>0)) { + memmove(cv->InBuff,&(cv->InBuff[cv->InPtr]),cv->InBuffCount); + cv->InPtr = 0; + } + + if (cv->InBuffCount<InBuffSize) { + switch (cv->PortType) { + case IdTCPIP: + C = Precv(cv->s, &(cv->InBuff[cv->InBuffCount]), + InBuffSize-cv->InBuffCount, 0); + if (C == SOCKET_ERROR) { + C = 0; + PWSAGetLastError(); + } + cv->InBuffCount = cv->InBuffCount + C; + break; + case IdSerial: + do { + ClearCommError(cv->ComID,&DErr,NULL); + if (! PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]), + InBuffSize-cv->InBuffCount,&C,&rol)) { + if (GetLastError() == ERROR_IO_PENDING) { + if (WaitForSingleObject(rol.hEvent, 1000) != WAIT_OBJECT_0) { + C = 0; + } + else { + GetOverlappedResult(cv->ComID,&rol,&C,FALSE); + } + } + else { + C = 0; + } + } + cv->InBuffCount = cv->InBuffCount + C; + } while ((C!=0) && (cv->InBuffCount<InBuffSize)); + ClearCommError(cv->ComID,&DErr,NULL); + break; + case IdFile: + if (PReadFile(cv->ComID,&(cv->InBuff[cv->InBuffCount]), + InBuffSize-cv->InBuffCount,&C,NULL)) { + if (C == 0) { + DErr = ERROR_HANDLE_EOF; + } + else { + cv->InBuffCount = cv->InBuffCount + C; + } + } + else { + DErr = GetLastError(); + } + break; + } + } + + if (cv->InBuffCount==0) { + switch (cv->PortType) { + case IdTCPIP: + if (! TCPIPClosed) { + PWSAAsyncSelect(cv->s,cv->HWin, WM_USER_COMMNOTIFY, + FD_READ | FD_OOB | FD_CLOSE); + } + break; + case IdSerial: + cv->RRQ = FALSE; + SetEvent(ReadEnd); + return; + case IdFile: + if (DErr != ERROR_IO_PENDING) { + PostMessage(cv->HWin, WM_USER_COMMNOTIFY, 0, FD_CLOSE); + cv->RRQ = FALSE; + } + else { + cv->RRQ = TRUE; + } + return; + } + cv->RRQ = FALSE; + } +} + +void CommSend(PComVar cv) +{ + int delay; + COMSTAT Stat; + BYTE LineEnd; + int C, D, Max; + DWORD DErr; + + if ((! cv->Open) || (! cv->Ready)) { + cv->OutBuffCount = 0; + return; + } + + if ((cv->OutBuffCount == 0) || (! cv->CanSend)) { + return; + } + + /* Max num of bytes to be written */ + switch (cv->PortType) { + case IdTCPIP: + if (TCPIPClosed) { + cv->OutBuffCount = 0; + } + Max = cv->OutBuffCount; + break; + case IdSerial: + ClearCommError(cv->ComID,&DErr,&Stat); + Max = OutBuffSize - Stat.cbOutQue; + break; + case IdFile: + Max = cv->OutBuffCount; + break; + } + + if ( Max<=0 ) { + return; + } + if ( Max > cv->OutBuffCount ) { + Max = cv->OutBuffCount; + } + + if (cv->PortType == IdTCPIP && cv->TelFlag) { + cv->LastSendTime = time(NULL); + } + + C = Max; + delay = 0; + + if ( cv->DelayFlag && (cv->PortType==IdSerial) ) { + if ( cv->DelayPerLine > 0 ) { + if ( cv->CRSend==IdCR ) { + LineEnd = 0x0d; + } + else { + LineEnd = 0x0a; + } + C = 1; + if ( cv->DelayPerChar==0 ) { + while ((C<Max) && (cv->OutBuff[cv->OutPtr+C-1]!=LineEnd)) { + C++; + } + } + if ( cv->OutBuff[cv->OutPtr+C-1]==LineEnd ) { + delay = cv->DelayPerLine; + } + else { + delay = cv->DelayPerChar; + } + } + else if ( cv->DelayPerChar > 0 ) { + C = 1; + delay = cv->DelayPerChar; + } + } + + /* Write to comm driver/Winsock */ + switch (cv->PortType) { + case IdTCPIP: + D = Psend(cv->s, &(cv->OutBuff[cv->OutPtr]), C, 0); + if ( D==SOCKET_ERROR ) { /* if error occurs */ + PWSAGetLastError(); /* Clear error */ + D = 0; + } + break; + + case IdSerial: + if (! PWriteFile(cv->ComID,&(cv->OutBuff[cv->OutPtr]),C,(LPDWORD)&D,&wol)) { + if (GetLastError() == ERROR_IO_PENDING) { + if (WaitForSingleObject(wol.hEvent,1000) != WAIT_OBJECT_0) { + D = C; /* Time out, ignore data */ + } + else { + GetOverlappedResult(cv->ComID,&wol,(LPDWORD)&D,FALSE); + } + } + else { /* I/O error */ + D = C; /* ignore error */ + } + } + ClearCommError(cv->ComID,&DErr,&Stat); + break; + + case IdFile: + if (! PWriteFile(cv->ComID, &(cv->OutBuff[cv->OutPtr]), C, (LPDWORD)&D, NULL)) { + if (! GetLastError() == ERROR_IO_PENDING) { + D = C; /* ignore data */ + } + } + break; + } + + cv->OutBuffCount = cv->OutBuffCount - D; + if ( cv->OutBuffCount==0 ) { + cv->OutPtr = 0; + } + else { + cv->OutPtr = cv->OutPtr + D; + } + + if ( (C==D) && (delay>0) ) { + cv->CanSend = FALSE; + SetTimer(cv->HWin, IdDelayTimer, delay, NULL); + } +} + +void CommSendBreak(PComVar cv) +/* for only serial ports */ +{ + MSG DummyMsg; + + if ( ! cv->Ready ) { + return; + } + + switch (cv->PortType) { + case IdSerial: + /* Set com port into a break state */ + SetCommBreak(cv->ComID); + + /* pause for 1 sec */ + if (SetTimer(cv->HWin, IdBreakTimer, 1000, NULL) != 0) { + GetMessage(&DummyMsg,cv->HWin,WM_TIMER,WM_TIMER); + } + + /* Set com port into the nonbreak state */ + ClearCommBreak(cv->ComID); + break; + } +} + +void CommLock(PTTSet ts, PComVar cv, BOOL Lock) +{ + BYTE b; + DWORD Func; + + if (! cv->Ready) { + return; + } + if ((cv->PortType==IdTCPIP) || + (cv->PortType==IdSerial) && + (ts->Flow!=IdFlowHard)) { + if (Lock) { + b = XOFF; + } + else { + b = XON; + } + CommBinaryOut(cv,&b,1); + } + else if ((cv->PortType==IdSerial) && + (ts->Flow==IdFlowHard)) { + if (Lock) { + Func = CLRRTS; + } + else { + Func = SETRTS; + } + EscapeCommFunction(cv->ComID,Func); + } +} + +int GetCommSerialBaudRate(int id) +{ + char *ch; + int val; + + // id-1ªXgÌindexÆÈéB + ch = BaudList[id - 1]; + val = atoi(ch); + return (val); +} + +BOOL PrnOpen(PCHAR DevName) +{ + char Temp[MAXPATHLEN]; + DCB dcb; + DWORD DErr; + COMMTIMEOUTS ctmo; + + strncpy_s(Temp, sizeof(Temp),DevName, _TRUNCATE); + Temp[4] = 0; // COMn or LPTn + LPTFlag = (Temp[0]=='L') || + (Temp[0]=='l'); + PrnID = CreateFile(Temp,GENERIC_WRITE, + 0,NULL,OPEN_EXISTING, + 0,NULL); + if (PrnID == INVALID_HANDLE_VALUE) { + return FALSE; + } + + if (GetCommState(PrnID,&dcb)) { + BuildCommDCB(DevName,&dcb); + SetCommState(PrnID,&dcb); + } + ClearCommError(PrnID,&DErr,NULL); + if (! LPTFlag) { + SetupComm(PrnID,0,CommOutQueSize); + } + /* flush output buffer */ + PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR); + memset(&ctmo,0,sizeof(ctmo)); + ctmo.WriteTotalTimeoutConstant = 1000; + SetCommTimeouts(PrnID,&ctmo); + if (! LPTFlag) { + EscapeCommFunction(PrnID,SETDTR); + } + return TRUE; +} + +int PrnWrite(PCHAR b, int c) +{ + int d; + DWORD DErr; + COMSTAT Stat; + + if (PrnID == INVALID_HANDLE_VALUE ) { + return c; + } + + ClearCommError(PrnID,&DErr,&Stat); + if (! LPTFlag && + (OutBuffSize - (int)Stat.cbOutQue < c)) { + c = OutBuffSize - Stat.cbOutQue; + } + if (c<=0) { + return 0; + } + if (! WriteFile(PrnID,b,c,(LPDWORD)&d,NULL)) { + d = 0; + } + ClearCommError(PrnID,&DErr,NULL); + return d; +} + +void PrnCancel() +{ + PurgeComm(PrnID, PURGE_TXABORT | PURGE_TXCLEAR); + PrnClose(); +} + +void PrnClose() +{ + if (PrnID != INVALID_HANDLE_VALUE) { + if (!LPTFlag) { + EscapeCommFunction(PrnID,CLRDTR); + } + CloseHandle(PrnID); + } + PrnID = INVALID_HANDLE_VALUE; +} Modified: trunk/teraterm/ttpfile/ttfile.c =================================================================== --- trunk/teraterm/ttpfile/ttfile.c 2010-04-12 12:51:24 UTC (rev 3854) +++ trunk/teraterm/ttpfile/ttfile.c 2010-04-12 13:43:07 UTC (rev 3855) @@ -1,1193 +1,1195 @@ -/* Tera Term - Copyright(C) 1994-1998 T. Teranishi - All rights reserved. */ - -/* TTFILE.DLL, file transfer, VT window printing */ -#include "teraterm.h" -#include "tttypes.h" -#include "ttftypes.h" -#include <direct.h> -#include <commdlg.h> -#include <string.h> - -#include "ttlib.h" -#include "ftlib.h" -#include "dlglib.h" -#include "kermit.h" -#include "xmodem.h" -#include "ymodem.h" -#include "zmodem.h" -#include "bplus.h" -#include "quickvan.h" -// resource IDs -#include "file_res.h" - -#include <stdlib.h> -#include <stdio.h> -#include <io.h> - -#include "compat_w95.h" - -static HANDLE hInst; - -static HFONT DlgFoptFont; -static HFONT DlgXoptFont; -static HFONT DlgGetfnFont; - -char UILanguageFile[MAX_PATH]; -char FileSendFilter[128]; - -BOOL FAR PASCAL GetSetupFname(HWND HWin, WORD FuncId, PTTSet ts) -{ - int i, j; - OPENFILENAME ofn; - char uimsg[MAX_UIMSG]; - - // char FNameFilter[HostNameMaxLength + 1]; // 81(yutaka) - char FNameFilter[81]; // 81(yutaka) - char TempDir[MAXPATHLEN]; - char Dir[MAXPATHLEN]; - char Name[MAXPATHLEN]; - BOOL Ok; - - /* save current dir */ - _getcwd(TempDir,sizeof(TempDir)); - - /* File name filter */ - memset(FNameFilter, 0, sizeof(FNameFilter)); - if (FuncId==GSF_LOADKEY) - { - get_lang_msg("FILEDLG_KEYBOARD_FILTER", uimsg, sizeof(uimsg), "keyboard setup files (*.cnf)\\0*.cnf\\0\\0", UILanguageFile); - memcpy(FNameFilter, uimsg, sizeof(FNameFilter)); - } - else { - get_lang_msg("FILEDLG_SETUP_FILTER", uimsg, sizeof(uimsg), "setup files (*.ini)\\0*.ini\\0\\0", UILanguageFile); - memcpy(FNameFilter, uimsg, sizeof(FNameFilter)); - } - - /* OPENFILENAME record */ - memset(&ofn, 0, sizeof(OPENFILENAME)); - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = HWin; - ofn.lpstrFile = Name; - ofn.nMaxFile = sizeof(Name); - ofn.lpstrFilter = FNameFilter; - ofn.nFilterIndex = 1; - ofn.hInstance = hInst; - - if (FuncId==GSF_LOADKEY) - { - ofn.lpstrDefExt = "cnf"; - GetFileNamePos(ts->KeyCnfFN,&i,&j); - strncpy_s(Name, sizeof(Name),&(ts->KeyCnfFN[j]), _TRUNCATE); - memcpy(Dir,ts->KeyCnfFN,i); - Dir[i] = 0; - - if ((strlen(Name)==0) || (_stricmp(Name,"KEYBOARD.CNF")==0)) - strncpy_s(Name, sizeof(Name),"KEYBOARD.CNF", _TRUNCATE); - } - else { - ofn.lpstrDefExt = "ini"; - GetFileNamePos(ts->SetupFName,&i,&j); - strncpy_s(Name, sizeof(Name),&(ts->SetupFName[j]), _TRUNCATE); - memcpy(Dir,ts->SetupFName,i); - Dir[i] = 0; - - if ((strlen(Name)==0) || (_stricmp(Name,"TERATERM.INI")==0)) - strncpy_s(Name, sizeof(Name),"TERATERM.INI", _TRUNCATE); - } - - if (strlen(Dir)==0) - strncpy_s(Dir, sizeof(Dir),ts->HomeDir, _TRUNCATE); - - _chdir(Dir); - - ofn.Flags = OFN_SHOWHELP | OFN_HIDEREADONLY; - switch (FuncId) { - case GSF_SAVE: - // út@CfBNgðvO{̪ éÓÉÅè·é (2005.1.6 yutaka) - // ÇÝÜê½teraterm.iniª éfBNgÉÅè·éB - // ±êÉæèA/F= Åwè³ê½ÊuÉÛ¶³êéæ¤ÉÈéB(2005.1.26 yutaka) - // Windows Vista ÅÍt@C¼ÜÅwè·éÆ NULL Ư¶®ð·éæ¤ÈÌÅA - // t@C¼ðÜÜÈ¢`ÅfBNgðwè·éæ¤Éµ½B(2006.9.16 maya) -// ofn.lpstrInitialDir = __argv[0]; -// ofn.lpstrInitialDir = ts->SetupFName; - ofn.lpstrInitialDir = Dir; - get_lang_msg("FILEDLG_SAVE_SETUP_TITLE", uimsg, sizeof(uimsg), "Tera Term: Save setup", UILanguageFile); - ofn.lpstrTitle = uimsg; - Ok = GetSaveFileName(&ofn); - if (Ok) - strncpy_s(ts->SetupFName, sizeof(ts->SetupFName),Name, _TRUNCATE); - break; - case GSF_RESTORE: - ofn.Flags = ofn.Flags | OFN_FILEMUSTEXIST; - get_lang_msg("FILEDLG_RESTORE_SETUP_TITLE", uimsg, sizeof(uimsg), "Tera Term: Restore setup", UILanguageFile); - ofn.lpstrTitle = uimsg; - Ok = GetOpenFileName(&ofn); - if (Ok) - strncpy_s(ts->SetupFName, sizeof(ts->SetupFName),Name, _TRUNCATE); - break; - case GSF_LOADKEY: - ofn.Flags = ofn.Flags | OFN_FILEMUSTEXIST; - get_lang_msg("FILEDLG_LOAD_KEYMAP_TITLE", uimsg, sizeof(uimsg), "Tera Term: Load key map", UILanguageFile); - ofn.lpstrTitle = uimsg; - Ok = GetOpenFileName(&ofn); - if (Ok) - strncpy_s(ts->KeyCnfFN, sizeof(ts->KeyCnfFN),Name, _TRUNCATE); - break; - } - - /* restore dir */ - _chdir(TempDir); - - return Ok; -} - -/* Hook function for file name dialog box */ -BOOL CALLBACK TFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam) -{ - LPOPENFILENAME ofn; - WORD Lo, Hi; - LPLONG pl; - LPOFNOTIFY notify; - char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG]; - LOGFONT logfont; - HFONT font; - - switch (Message) { - case WM_INITDIALOG: - ofn = (LPOPENFILENAME)lParam; - pl = (LPLONG)(ofn->lCustData); - SetWindowLong(Dialog, DWL_USER, (LONG)pl); - - font = (HFONT)SendMessage(Dialog, WM_GETFONT, 0, 0); - GetObject(font, sizeof(LOGFONT), &logfont); - if (get_lang_font("DLG_TAHOMA_FONT", Dialog, &logfont, &DlgFoptFont, UILanguageFile)) { - SendDlgItemMessage(Dialog, IDC_FOPT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_FOPTBIN, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_FOPTAPPEND, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_PLAINTEXT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_TIMESTAMP, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_HIDEDIALOG, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - } - else { - DlgFoptFont = NULL; - } - - GetDlgItemText(Dialog, IDC_FOPT, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_FOPT", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_FOPT, uimsg); - GetDlgItemText(Dialog, IDC_FOPTBIN, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_FOPT_BINARY", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_FOPTBIN, uimsg); - GetDlgItemText(Dialog, IDC_FOPTAPPEND, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_FOPT_APPEND", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_FOPTAPPEND, uimsg); - GetDlgItemText(Dialog, IDC_PLAINTEXT, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_FOPT_PLAIN", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_PLAINTEXT, uimsg); - GetDlgItemText(Dialog, IDC_TIMESTAMP, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_FOPT_TIMESTAMP", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_TIMESTAMP, uimsg); - GetDlgItemText(Dialog, IDC_HIDEDIALOG, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_FOPT_HIDEDIALOG", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_HIDEDIALOG, uimsg); - - Lo = LOWORD(*pl) & 1; - Hi = HIWORD(*pl); - SetRB(Dialog,Lo,IDC_FOPTBIN,IDC_FOPTBIN); - if (Hi!=0xFFFF) - { - ShowDlgItem(Dialog,IDC_FOPTAPPEND,IDC_FOPTAPPEND); - SetRB(Dialog,Hi & 1,IDC_FOPTAPPEND,IDC_FOPTAPPEND); - - // plain text`FbN{bNXÍftHgÅON (2005.2.20 yutaka) - ShowDlgItem(Dialog,IDC_PLAINTEXT,IDC_PLAINTEXT); - if (Lo) { - // BinarytOªLøÈÆ«Í`FbNÅ«È¢ - DisableDlgItem(Dialog,IDC_PLAINTEXT,IDC_PLAINTEXT); - } - else if (Hi & 0x1000) { - SetRB(Dialog,1,IDC_PLAINTEXT,IDC_PLAINTEXT); - } - - // timestamp`FbN{bNX (2006.7.23 maya) - ShowDlgItem(Dialog,IDC_TIMESTAMP,IDC_TIMESTAMP); - if (Lo) { - // BinarytOªLøÈÆ«Í`FbNÅ«È¢ - DisableDlgItem(Dialog,IDC_TIMESTAMP,IDC_TIMESTAMP); - } - else if (Hi & 0x2000) { - SetRB(Dialog,1,IDC_TIMESTAMP,IDC_TIMESTAMP); - } - - // Hide dialog`FbN{bNX (2008.1.30 maya) - ShowDlgItem(Dialog,IDC_HIDEDIALOG,IDC_HIDEDIALOG); - if (Hi & 0x4000) { - SetRB(Dialog,1,IDC_HIDEDIALOG,IDC_HIDEDIALOG); - } - } - return TRUE; - - case WM_COMMAND: // for old style dialog - switch (LOWORD(wParam)) { - case IDOK: - pl = (LPLONG)GetWindowLong(Dialog,DWL_USER); - if (pl!=NULL) - { - GetRB(Dialog,&Lo,IDC_FOPTBIN,IDC_FOPTBIN); - Hi = HIWORD(*pl); - if (Hi!=0xFFFF) - GetRB(Dialog,&Hi,IDC_FOPTAPPEND,IDC_FOPTAPPEND); - *pl = MAKELONG(Lo,Hi); - } - break; - case IDCANCEL: - break; - case IDC_FOPTBIN: - GetRB(Dialog,&Lo,IDC_FOPTBIN,IDC_FOPTBIN); - if (Lo) { - DisableDlgItem(Dialog,IDC_PLAINTEXT,IDC_TIMESTAMP); - } - else { - EnableDlgItem(Dialog,IDC_PLAINTEXT,IDC_TIMESTAMP); - } - break; - } - break; - case WM_NOTIFY: // for Explorer-style dialog - notify = (LPOFNOTIFY)lParam; - switch (notify->hdr.code) { - case CDN_FILEOK: - pl = (LPLONG)GetWindowLong(Dialog,DWL_USER); - if (pl!=NULL) - { - WORD val = 0; - - GetRB(Dialog,&Lo,IDC_FOPTBIN,IDC_FOPTBIN); - Hi = HIWORD(*pl); - if (Hi!=0xFFFF) - GetRB(Dialog,&Hi,IDC_FOPTAPPEND,IDC_FOPTAPPEND); - - if (!Lo) { - // plain text check-box - GetRB(Dialog,&val,IDC_PLAINTEXT,IDC_PLAINTEXT); - if (val > 0) { // checked - Hi |= 0x1000; - } - - // timestamp`FbN{bNX (2006.7.23 maya) - GetRB(Dialog,&val,IDC_TIMESTAMP,IDC_TIMESTAMP); - if (val > 0) { - Hi |= 0x2000; - } - } - - // Hide dialog`FbN{bNX (2008.1.30 maya) - GetRB(Dialog,&val,IDC_HIDEDIALOG,IDC_HIDEDIALOG); - if (val > 0) { - Hi |= 0x4000; - } - - *pl = MAKELONG(Lo,Hi); - } - if (DlgFoptFont != NULL) { - DeleteObject(DlgFoptFont); - } - break; - } - break; - } - return FALSE; -} - -BOOL FAR PASCAL GetTransFname - (PFileVar fv, PCHAR CurDir, WORD FuncId, LPLONG Option) -{ - char uimsg[MAX_UIMSG]; - char FNFilter[sizeof(FileSendFilter)*3], *pf; - OPENFILENAME ofn; - LONG opt; - char TempDir[MAXPATHLEN]; - BOOL Ok; - char FileName[MAX_PATH]; - - /* save current dir */ - _getcwd(TempDir,sizeof(TempDir)); - - memset(FNFilter, 0, sizeof(FNFilter)); /* Set up for double null at end */ - memset(&ofn, 0, sizeof(OPENFILENAME)); - - strncpy_s(fv->DlgCaption, sizeof(fv->DlgCaption),"Tera Term: ", _TRUNCATE); - pf = FNFilter; - switch (FuncId) { - case GTF_SEND: - get_lang_msg("FILEDLG_TRANS_TITLE_SENDFILE", uimsg, sizeof(uimsg), TitSendFile, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - if (strlen(FileSendFilter) > 0) { - get_lang_msg("FILEDLG_USER_FILTER_NAME", uimsg, sizeof(uimsg), "User define", UILanguageFile); - _snprintf_s(FNFilter, sizeof(FNFilter), _TRUNCATE, "%s(%s)", uimsg, FileSendFilter); - pf = pf + strlen(FNFilter) + 1; - strncpy_s(pf, sizeof(FNFilter)-(pf - FNFilter) ,FileSendFilter, _TRUNCATE); - pf = pf + strlen(pf) + 1; - } - break; - case GTF_LOG: - get_lang_msg("FILEDLG_TRANS_TITLE_LOG", uimsg, sizeof(uimsg), TitLog, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case GTF_BP: - get_lang_msg("FILEDLG_TRANS_TITLE_BPSEND", uimsg, sizeof(uimsg), TitBPSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - if (strlen(FileSendFilter) > 0) { - get_lang_msg("FILEDLG_USER_FILTER_NAME", uimsg, sizeof(uimsg), "User define", UILanguageFile); - _snprintf_s(FNFilter, sizeof(FNFilter), _TRUNCATE, "%s(%s)", uimsg, FileSendFilter); - pf = pf + strlen(FNFilter) + 1; - strncpy_s(pf, sizeof(FNFilter)-(pf - FNFilter) ,FileSendFilter, _TRUNCATE); - pf = pf + strlen(pf) + 1; - } - break; - default: return FALSE; - } - - get_lang_msg("FILEDLG_ALL_FILTER", uimsg, sizeof(uimsg), "All(*.*)\\0*.*\\0\\0", UILanguageFile); - // \0\0 ÅIíéKvª éÌÅ 2 oCg - memcpy(pf, uimsg, sizeof(FNFilter) - (pf - FNFilter + 2)); - - ExtractFileName(fv->FullName, FileName ,sizeof(FileName)); - strncpy_s(fv->FullName, sizeof(fv->FullName), FileName, _TRUNCATE); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = fv->HMainWin; - ofn.lpstrFilter = FNFilter; - ofn.nFilterIndex = 1; - ofn.lpstrFile = fv->FullName; - ofn.nMaxFile = sizeof(fv->FullName); - if (FuncId == GTF_LOG) { - DWORD logdir = GetFileAttributes(fv->LogDefaultPath); - // OÛ¶ÌêÍútH_ðßÅ¿µÈ¢æ¤É·éB(2007.8.24 yutaka) - if (logdir != -1 && logdir & FILE_ATTRIBUTE_DIRECTORY) { - // LogDefaultPathª¶Ý·éÈçA»±ðútH_É·éB(2007.11.30 maya) - ofn.lpstrInitialDir = fv->LogDefaultPath; - } - else { - ofn.lpstrInitialDir = NULL; - } - } else { - ofn.lpstrInitialDir = CurDir; - } - ofn.Flags = OFN_SHOWHELP | OFN_HIDEREADONLY; - if (FuncId!=GTF_BP) - { - ofn.Flags = ofn.Flags | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK; - ofn.Flags = ofn.Flags | OFN_EXPLORER; - ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FOPT); - ofn.lpfnHook = (LPOFNHOOKPROC)(&TFnHook); - } - opt = *Option; - if (FuncId!=GTF_LOG) - { - ofn.Flags = ofn.Flags | OFN_FILEMUSTEXIST; - opt = MAKELONG(LOWORD(*Option),0xFFFF); - - // tB^ªChJ[hÅÍÈA»Ìt@Cª¶Ý·éê - // 究ßftHgÌt@C¼ðüêĨ (2008.5.18 maya) - if (strlen(FileSendFilter) > 0 && - !isInvalidFileNameChar(FileSendFilter)) { - char file[MAX_PATH]; - strncpy_s(file, sizeof(file), CurDir, _TRUNCATE); - AppendSlash(file, sizeof(file)); - strncat_s(file, sizeof(file), FileSendFilter, _TRUNCATE); - if (_access(file, 0) == 0) { - strncpy_s(fv->FullName, sizeof(fv->FullName), FileSendFilter, _TRUNCATE); - } - } - } - ofn.lCustData = (DWORD)&opt; - ofn.lpstrTitle = fv->DlgCaption; - - ofn.hInstance = hInst; - - // loggingÌêAI[v_CAOðZ[u_CAOÖÏX (2005.1.6 yutaka) - if (FuncId == GTF_LOG) { - // OÌftHgl(log_YYYYMMDD_HHMMSS.txt)ðÝè·é (2005.1.21 yutaka) - // ftHgt@C¼ð teraterm.log ÖÏX (2005.2.22 yutaka) - // ftHgt@C¼ÌÝèêðÄÑoµ³ÖÚ® (2006.8.28 maya) - Ok = GetSaveFileName(&ofn); - } else { - Ok = GetOpenFileName(&ofn); - } - - if (Ok) - { - if (FuncId==GTF_LOG) - *Option = opt; - else - *Option = MAKELONG(LOWORD(opt),HIWORD(*Option)); - - fv->DirLen = ofn.nFileOffset; - - if (CurDir!=NULL) - { - memcpy(CurDir,fv->FullName,fv->DirLen-1); - CurDir[fv->DirLen-1] = 0; - } - } - /* restore dir */ - _chdir(TempDir); - return Ok; -} - -BOOL CALLBACK TFn2Hook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam) -{ - LPOPENFILENAME ofn; - LPWORD pw; - LPOFNOTIFY notify; - char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG]; - LOGFONT logfont; - HFONT font; - - switch (Message) { - case WM_INITDIALOG: - ofn = (LPOPENFILENAME)lParam; - pw = (LPWORD)ofn->lCustData; - SetWindowLong(Dialog, DWL_USER, (LONG)pw); - - font = (HFONT)SendMessage(Dialog, WM_GETFONT, 0, 0); - GetObject(font, sizeof(LOGFONT), &logfont); - if (get_lang_font("DLG_TAHOMA_FONT", Dialog, &logfont, &DlgFoptFont, UILanguageFile)) { - SendDlgItemMessage(Dialog, IDC_FOPT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_FOPTBIN, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_FOPTAPPEND, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_PLAINTEXT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_TIMESTAMP, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - } - else { - DlgFoptFont = NULL; - } - - GetDlgItemText(Dialog, IDC_FOPT, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_FOPT", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_FOPT, uimsg); - GetDlgItemText(Dialog, IDC_FOPTBIN, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_FOPT_BINARY", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_FOPTBIN, uimsg); - - SetRB(Dialog,*pw & 1,IDC_FOPTBIN,IDC_FOPTBIN); - return TRUE; - case WM_COMMAND: // for old style dialog - switch (LOWORD(wParam)) { - case IDOK: - pw = (LPWORD)GetWindowLong(Dialog,DWL_USER); - if (pw!=NULL) - GetRB(Dialog,pw,IDC_FOPTBIN,IDC_FOPTBIN); - break; - case IDCANCEL: - break; - } - break; - case WM_NOTIFY: // for Explorer-style dialog - notify = (LPOFNOTIFY)lParam; - switch (notify->hdr.code) { - case CDN_FILEOK: - pw = (LPWORD)GetWindowLong(Dialog,DWL_USER); - if (pw!=NULL) - GetRB(Dialog,pw,IDC_FOPTBIN,IDC_FOPTBIN); - if (DlgFoptFont != NULL) { - DeleteObject(DlgFoptFont); - } - break; - } - break; - } - return FALSE; -} - -BOOL FAR PASCAL GetMultiFname - (PFileVar fv, PCHAR CurDir, WORD FuncId, LPWORD Option) -{ - int i, len; - char uimsg[MAX_UIMSG]; - char FNFilter[sizeof(FileSendFilter)*2+128], *pf; - OPENFILENAME ofn; - char TempDir[MAXPATHLEN]; - BOOL Ok; - char defaultFName[MAX_PATH]; - - memset(FNFilter, 0, sizeof(FNFilter)); /* Set up for double null at end */ - - /* save current dir */ - _getcwd(TempDir,sizeof(TempDir)); - - fv->NumFname = 0; - - strncpy_s(fv->DlgCaption, sizeof(fv->DlgCaption),"Tera Term: ", _TRUNCATE); - pf = FNFilter; - switch (FuncId) { - case GMF_KERMIT: - get_lang_msg("FILEDLG_TRANS_TITLE_KMTSEND", uimsg, sizeof(uimsg), TitKmtSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case GMF_Z: - get_lang_msg("FILEDLG_TRANS_TITLE_ZSEND", uimsg, sizeof(uimsg), TitZSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case GMF_QV: - get_lang_msg("FILEDLG_TRANS_TITLE_QVSEND", uimsg, sizeof(uimsg), TitQVSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case GMF_Y: - get_lang_msg("FILEDLG_TRANS_TITLE_YSEND", uimsg, sizeof(uimsg), TitYSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - default: - return FALSE; - } - if (strlen(FileSendFilter) > 0) { - get_lang_msg("FILEDLG_USER_FILTER_NAME", uimsg, sizeof(uimsg), "User define", UILanguageFile); - _snprintf_s(FNFilter, sizeof(FNFilter), _TRUNCATE, "%s(%s)", uimsg, FileSendFilter); - pf = pf + strlen(FNFilter) + 1; - strncpy_s(pf, sizeof(FNFilter)-(pf - FNFilter) ,FileSendFilter, _TRUNCATE); - pf = pf + strlen(pf) + 1; - } - - /* moemory should be zero-initialized */ - fv->FnStrMemHandle = GlobalAlloc(GHND, FnStrMemSize); - if (fv->FnStrMemHandle == NULL) - { - MessageBeep(0); - return FALSE; - } - else { - fv->FnStrMem = GlobalLock(fv->FnStrMemHandle); - if (fv->FnStrMem == NULL) - { - GlobalFree(fv->FnStrMemHandle); - fv->FnStrMemHandle = 0; - MessageBeep(0); - return FALSE; - } - } - - get_lang_msg("FILEDLG_ALL_FILTER", uimsg, sizeof(uimsg), "All(*.*)\\0*.*\\0\\0", UILanguageFile); - // \0\0 ÅIíéKvª éÌÅ 2 oCg - memcpy(pf, uimsg, sizeof(FNFilter) - (pf - FNFilter + 2)); - - memset(&ofn, 0, sizeof(OPENFILENAME)); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = fv->HMainWin; - ofn.lpstrFilter = FNFilter; - ofn.nFilterIndex = 1; - ofn.lpstrFile = fv->FnStrMem; - ofn.nMaxFile = FnStrMemSize; - ofn.lpstrTitle= fv->DlgCaption; - ofn.lpstrInitialDir = CurDir; - ofn.Flags = OFN_SHOWHELP | OFN_ALLOWMULTISELECT | - OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; - ofn.Flags = ofn.Flags | OFN_EXPLORER; - ofn.lCustData = 0; - if (FuncId==GMF_Z) - { - ofn.Flags = ofn.Flags | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK; - ofn.lCustData = (DWORD)Option; - ofn.lpfnHook = (LPOFNHOOKPROC)(&TFn2Hook); - ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FOPT); - } else if (FuncId==GMF_Y) { - // TODO: YMODEM - - } - - ofn.hInstance = hInst; - - // tB^ªChJ[hÅÍÈA»Ìt@Cª¶Ý·éê - // 究ßftHgÌt@C¼ðüêĨ (2008.5.18 maya) - if (strlen(FileSendFilter) > 0 && - !isInvalidFileNameChar(FileSendFilter)) { - char file[MAX_PATH]; - strncpy_s(file, sizeof(file), CurDir, _TRUNCATE); - AppendSlash(file, sizeof(file)); - strncat_s(file, sizeof(file), FileSendFilter, _TRUNCATE); - if (_access(file, 0) == 0) { - strncpy_s(defaultFName, sizeof(defaultFName), FileSendFilter, _TRUNCATE); - ofn.lpstrFile = defaultFName; - } - } - - Ok = GetOpenFileName(&ofn); - if (Ok) - { - /* count number of file names */ - len = strlen(fv->FnStrMem); - i = 0; - while (len>0) - { - i = i + len + 1; - fv->NumFname++; - len = strlen(&fv->FnStrMem[i]); - } - - fv->NumFname--; - - if (fv->NumFname<1) - { // single selection - fv->NumFname = 1; - fv->DirLen = ofn.nFileOffset; - strncpy_s(fv->FullName, sizeof(fv->FullName),fv->FnStrMem, _TRUNCATE); - fv->FnPtr = 0; - } - else { // multiple selection - strncpy_s(fv->FullName, sizeof(fv->FullName),fv->FnStrMem, _TRUNCATE); - AppendSlash(fv->FullName,sizeof(fv->FullName)); - fv->DirLen = strlen(fv->FullName); - fv->FnPtr = strlen(fv->FnStrMem)+1; - } - - memcpy(CurDir,fv->FullName,fv->DirLen); - CurDir[fv->DirLen] = 0; - if ((fv->DirLen>3) && - (CurDir[fv->DirLen-1]=='\\')) - CurDir[fv->DirLen-1] = 0; - - fv->FNCount = 0; - } - - GlobalUnlock(fv->FnStrMemHandle); - if (! Ok) - { - GlobalFree(fv->FnStrMemHandle); - fv->FnStrMemHandle = NULL; - } - - /* restore dir */ - _chdir(TempDir); - - return Ok; -} - -BOOL CALLBACK GetFnDlg - (HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam) -{ - PFileVar fv; - char TempFull[MAXPATHLEN]; - int i, j; - char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG]; - LOGFONT logfont; - HFONT font; - - switch (Message) { - case WM_INITDIALOG: - fv = (PFileVar)lParam; - SetWindowLong(Dialog, DWL_USER, lParam); - SendDlgItemMessage(Dialog, IDC_GETFN, EM_LIMITTEXT, sizeof(TempFull)-1,0); - - font = (HFONT)SendMessage(Dialog, WM_GETFONT, 0, 0); - GetObject(font, sizeof(LOGFONT), &logfont); - if (get_lang_font("DLG_SYSTEM_FONT", Dialog, &logfont, &DlgGetfnFont, UILanguageFile)) { - SendDlgItemMessage(Dialog, IDC_FILENAME, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_GETFN, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDOK, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDCANCEL, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_GETFNHELP, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); - } - else { - DlgGetfnFont = NULL; - } - - GetWindowText(Dialog, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_GETFN_TITLE", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetWindowText(Dialog, uimsg); - GetDlgItemText(Dialog, IDC_FILENAME, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_GETFN_FILENAME", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_FILENAME, uimsg); - GetDlgItemText(Dialog, IDOK, uimsg2, sizeof(uimsg2)); - get_lang_msg("BTN_OK", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDOK, uimsg); - GetDlgItemText(Dialog, IDCANCEL, uimsg2, sizeof(uimsg2)); - get_lang_msg("BTN_CANCEL", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDCANCEL, uimsg); - GetDlgItemText(Dialog, IDC_GETFNHELP, uimsg2, sizeof(uimsg2)); - get_lang_msg("BTN_HELP", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_GETFNHELP, uimsg); - - return TRUE; - - case WM_COMMAND: - fv = (PFileVar)GetWindowLong(Dialog,DWL_USER); - switch (LOWORD(wParam)) { - case IDOK: - if (fv!=NULL) - { - GetDlgItemText(Dialog, IDC_GETFN, TempFull, sizeof(TempFull)); - if (strlen(TempFull)==0) return TRUE; - GetFileNamePos(TempFull,&i,&j); - FitFileName(&(TempFull[j]),sizeof(TempFull) - j, NULL); - strncat_s(fv->FullName,sizeof(fv->FullName),&(TempFull[j]),_TRUNCATE); - } - EndDialog(Dialog, 1); - if (DlgGetfnFont != NULL) { - DeleteObject(DlgGetfnFont); - } - return TRUE; - case IDCANCEL: - EndDialog(Dialog, 0); - if (DlgGetfnFont != NULL) { - DeleteObject(DlgGetfnFont); - } - return TRUE; - case IDC_GETFNHELP: - if (fv!=NULL) - PostMessage(fv->HMainWin,WM_USER_DLGHELP2,0,0); - break; - } - } - return FALSE; -} - -BOOL FAR PASCAL GetGetFname(HWND HWin, PFileVar fv) -{ - return (BOOL)DialogBoxParam(hInst, - MAKEINTRESOURCE(IDD_GETFNDLG), - HWin, GetFnDlg, (LONG)fv); -} - -void FAR PASCAL SetFileVar(PFileVar fv) -{ - int i; - char uimsg[MAX_UIMSG]; - - GetFileNamePos(fv->FullName,&(fv->DirLen),&i); - if (fv->FullName[fv->DirLen]=='\\') fv->DirLen++; - strncpy_s(fv->DlgCaption, sizeof(fv->DlgCaption),"Tera Term: ", _TRUNCATE); - switch (fv->OpId) { - case OpLog: - get_lang_msg("FILEDLG_TRANS_TITLE_LOG", uimsg, sizeof(uimsg), TitLog, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpSendFile: - get_lang_msg("FILEDLG_TRANS_TITLE_SENDFILE", uimsg, sizeof(uimsg), TitSendFile, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpKmtRcv: - get_lang_msg("FILEDLG_TRANS_TITLE_KMTRCV", uimsg, sizeof(uimsg), TitKmtRcv, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpKmtGet: - get_lang_msg("FILEDLG_TRANS_TITLE_KMTGET", uimsg, sizeof(uimsg), TitKmtGet, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpKmtSend: - get_lang_msg("FILEDLG_TRANS_TITLE_KMTSEND", uimsg, sizeof(uimsg), TitKmtSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpKmtFin: - get_lang_msg("FILEDLG_TRANS_TITLE_KMTFIN", uimsg, sizeof(uimsg), TitKmtFin, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpXRcv: - get_lang_msg("FILEDLG_TRANS_TITLE_XRCV", uimsg, sizeof(uimsg), TitXRcv, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpXSend: - get_lang_msg("FILEDLG_TRANS_TITLE_XSEND", uimsg, sizeof(uimsg), TitXSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpYRcv: - get_lang_msg("FILEDLG_TRANS_TITLE_YRCV", uimsg, sizeof(uimsg), TitYRcv, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpYSend: - get_lang_msg("FILEDLG_TRANS_TITLE_YSEND", uimsg, sizeof(uimsg), TitYSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpZRcv: - get_lang_msg("FILEDLG_TRANS_TITLE_ZRCV", uimsg, sizeof(uimsg), TitZRcv, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpZSend: - get_lang_msg("FILEDLG_TRANS_TITLE_ZSEND", uimsg, sizeof(uimsg), TitZSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpBPRcv: - get_lang_msg("FILEDLG_TRANS_TITLE_BPRCV", uimsg, sizeof(uimsg), TitBPRcv, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpBPSend: - get_lang_msg("FILEDLG_TRANS_TITLE_BPSEND", uimsg, sizeof(uimsg), TitBPSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpQVRcv: - get_lang_msg("FILEDLG_TRANS_TITLE_QVRCV", uimsg, sizeof(uimsg), TitQVRcv, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - case OpQVSend: - get_lang_msg("FILEDLG_TRANS_TITLE_QVSEND", uimsg, sizeof(uimsg), TitQVSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - break; - } -} - -/* Hook function for XMODEM file name dialog box */ -BOOL CALLBACK XFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam) -{ - LPOPENFILENAME ofn; - WORD Hi, Lo; - LPLONG pl; - LPOFNOTIFY notify; - char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG]; - LOGFONT logfont; - HFONT font; - - switch (Message) { - case WM_INITDIALOG: - ofn = (LPOPENFILENAME)lParam; - pl = (LPLONG)ofn->lCustData; - SetWindowLong(Dialog, DWL_USER, (LONG)pl); - - font = (HFONT)SendMessage(Dialog, WM_GETFONT, 0, 0); - GetObject(font, sizeof(LOGFONT), &logfont); - if (get_lang_font("DLG_TAHOMA_FONT", Dialog, &logfont, &DlgFoptFont, UILanguageFile)) { - SendDlgItemMessage(Dialog, IDC_XOPT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_XOPTCHECK, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_XOPTCRC, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_XOPT1K, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - SendDlgItemMessage(Dialog, IDC_XOPTBIN, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); - } - else { - DlgFoptFont = NULL; - } - - GetDlgItemText(Dialog, IDC_XOPT, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_XOPT", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_XOPT, uimsg); - GetDlgItemText(Dialog, IDC_XOPTCHECK, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_XOPT_CHECKSUM", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_XOPTCHECK, uimsg); - GetDlgItemText(Dialog, IDC_XOPTCRC, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_XOPT_CRC", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_XOPTCRC, uimsg); - GetDlgItemText(Dialog, IDC_XOPT1K, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_XOPT_1K", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_XOPT1K, uimsg); - GetDlgItemText(Dialog, IDC_XOPTBIN, uimsg2, sizeof(uimsg2)); - get_lang_msg("DLG_XOPT_BINARY", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); - SetDlgItemText(Dialog, IDC_XOPTBIN, uimsg); - - SetRB(Dialog,HIWORD(*pl),IDC_XOPTCHECK,IDC_XOPT1K); - if (LOWORD(*pl)!=0xFFFF) - { - ShowDlgItem(Dialog,IDC_XOPTBIN,IDC_XOPTBIN); - SetRB(Dialog,LOWORD(*pl),IDC_XOPTBIN,IDC_XOPTBIN); - } - return TRUE; - case WM_COMMAND: // for old style dialog - switch (LOWORD(wParam)) { - case IDOK: - pl = (LPLONG)GetWindowLong(Dialog,DWL_USER); - if (pl!=NULL) - { - GetRB(Dialog,&Hi,IDC_XOPTCHECK,IDC_XOPT1K); - if (LOWORD(*pl)==0xFFFF) - Lo = 0xFFFF; - else - GetRB(Dialog,&Lo,IDC_XOPTBIN,IDC_XOPTBIN); - *pl = MAKELONG(Lo,Hi); - } - break; - case IDCANCEL: - break; - } - break; - case WM_NOTIFY: // for Explorer-style dialog - notify = (LPOFNOTIFY)lParam; - switch (notify->hdr.code) { - case CDN_FILEOK: - pl = (LPLONG)GetWindowLong(Dialog,DWL_USER); - if (pl!=NULL) - { - GetRB(Dialog,&Hi,IDC_XOPTCHECK,IDC_XOPT1K); - if (LOWORD(*pl)==0xFFFF) - Lo = 0xFFFF; - else - GetRB(Dialog,&Lo,IDC_XOPTBIN,IDC_XOPTBIN); - *pl = MAKELONG(Lo,Hi); - } - if (DlgXoptFont != NULL) { - DeleteObject(DlgXoptFont); - } - break; - } - break; - } - return FALSE; -} - -BOOL FAR PASCAL GetXFname - (HWND HWin, BOOL Receive, LPLONG Option, PFileVar fv, PCHAR CurDir) -{ - char uimsg[MAX_UIMSG]; - char FNFilter[sizeof(FileSendFilter)*2+128], *pf; - OPENFILENAME ofn; - LONG opt; - char TempDir[MAXPATHLEN]; - BOOL Ok; - - memset(FNFilter, 0, sizeof(FNFilter)); /* Set up for double null at end */ - - /* save current dir */ - _getcwd(TempDir,sizeof(TempDir)); - - fv->FullName[0] = 0; - memset(FNFilter, 0, sizeof(FNFilter)); /* Set up for double null at end */ - memset(&ofn, 0, sizeof(OPENFILENAME)); - - strncpy_s(fv->DlgCaption, sizeof(fv->DlgCaption),"Tera Term: ", _TRUNCATE); - pf = FNFilter; - if (Receive) - { - get_lang_msg("FILEDLG_TRANS_TITLE_XRCV", uimsg, sizeof(uimsg), TitXRcv, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - } - else - { - get_lang_msg("FILEDLG_TRANS_TITLE_XSEND", uimsg, sizeof(uimsg), TitXSend, UILanguageFile); - strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); - if (strlen(FileSendFilter) > 0) { - get_lang_msg("FILEDLG_USER_FILTER_NAME", uimsg, sizeof(uimsg), "User define", UILanguageFile); - _snprintf_s(FNFilter, sizeof(FNFilter), _TRUNCATE, "%s(%s)", uimsg, FileSendFilter); - pf = pf + strlen(FNFilter) + 1; - strncpy_s(pf, sizeof(FNFilter)-(pf - FNFilter) ,FileSendFilter, _TRUNCATE); - pf = pf + strlen(pf) + 1; - - // tB^ªChJ[hÅÍÈA»Ìt@Cª¶Ý·éê - // 究ßftHgÌt@C¼ðüêĨ (2008.5.18 maya) - if (!isInvalidFileNameChar(FileSendFilter)) { - char file[MAX_PATH]; - strncpy_s(file, sizeof(file), CurDir, _TRUNCATE); - AppendSlash(file, sizeof(file)); - strncat_s(file, sizeof(file), FileSendFilter, _TRUNCATE); - if (_access(file, 0) == 0) { - strncpy_s(fv->FullName, sizeof(fv->FullName), FileSendFilter, _TRUNCATE); - } - } - } - } - - get_lang_msg("FILEDLG_ALL_FILTER", uimsg, sizeof(uimsg), "All(*.*)\\0*.*\\0\\0", UILanguageFile); - // \0\0 ÅIíéKvª éÌÅ 2 oCg - memcpy(pf, uimsg, sizeof(FNFilter) - (pf - FNFilter + 2)); - - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = HWin; - ofn.lpstrFilter = FNFilter; - ofn.nFilterIndex = 1; - ofn.lpstrFile = fv->FullName; - ofn.nMaxFile = sizeof(fv->FullName); - ofn.lpstrInitialDir = CurDir; - ofn.Flags = OFN_SHOWHELP | OFN_HIDEREADONLY | - OFN_ENABLETEMPLATE | OFN_ENABLEHOOK; - opt = *Option; - if (! Receive) - { - ofn.Flags = ofn.Flags | OFN_FILEMUSTEXIST; - opt = opt | 0xFFFF; - } - ofn.lCustData = (DWORD)&opt; - - ofn.lpstrTitle = fv->DlgCaption; - ofn.lpfnHook = (LPOFNHOOKPROC)(&XFnHook); - ofn.Flags = ofn.Flags | OFN_EXPLORER; - ofn.lpTemplateName = MAKEINTRESOURCE(IDD_XOPT); - ofn.hInstance = hInst; - - Ok = GetOpenFileName(&ofn); - - if (Ok) - { - fv->DirLen = ofn.nFileOffset; - fv->FnPtr = ofn.nFileOffset; - memcpy(CurDir,fv->FullName,fv->DirLen-1); - CurDir[fv->DirLen-1] = 0; - - if (Receive) - *Option = opt; - else - *Option = MAKELONG(LOWORD(*Option),HIWORD(opt)); - } - - /* restore dir */ - _chdir(TempDir); - - return Ok; -} - -void FAR PASCAL ProtoInit(int Proto, PFileVar fv, PCHAR pv, PComVar cv, PTTSet ts) -{ - switch (Proto) { - case PROTO_KMT: - KmtInit(fv,(PKmtVar)pv,cv,ts); - break; - case PROTO_XM: - XInit(fv,(PXVar)pv,cv,ts); - break; - case PROTO_YM: - YInit(fv,(PYVar)pv,cv,ts); - break; - case PROTO_ZM: - ZInit(fv,(PZVar)pv,cv,ts); - break; - case PROTO_BP: - BPInit(fv,(PBPVar)pv,cv,ts); - break; - case PROTO_QV: - QVInit(fv,(PQVVar)pv,cv,ts); - break; - } -} - -BOOL FAR PASCAL ProtoParse - (int Proto, PFileVar fv, PCHAR pv, PComVar cv) -{ - BOOL Ok; - - Ok = FALSE; - switch (Proto) { - case PROTO_KMT: - Ok = KmtReadPacket(fv,(PKmtVar)pv,cv); - break; - case PROTO_XM: - switch (((PXVar)pv)->XMode) { - case IdXReceive: - Ok = XReadPacket(fv,(PXVar)pv,cv); - break; - case IdXSend: - Ok = XSendPacket(fv,(PXVar)pv,cv); - break; - } - break; - case PROTO_YM: - switch (((PYVar)pv)->YMode) { - case IdYReceive: - Ok = YReadPacket(fv,(PYVar)pv,cv); - break; - case IdYSend: - Ok = YSendPacket(fv,(PYVar)pv,cv); - break; - } - break; - case PROTO_ZM: - Ok = ZParse(fv,(PZVar)pv,cv); - break; - case PROTO_BP: - Ok = BPParse(fv,(PBPVar)pv,cv); - break; - case PROTO_QV: - switch (((PQVVar)pv)->QVMode) { - case IdQVReceive: - Ok = QVReadPacket(fv,(PQVVar)pv,cv); - break; - case IdQVSend: - Ok = QVSendPacket(fv,(PQVVar)pv,cv); - break; - } - break; - } - return Ok; -} - -void FAR PASCAL ProtoTimeOutProc - (int Proto, PFileVar fv, PCHAR pv, PComVar cv) -{ - switch (Proto) { - case PROTO_KMT: - KmtTimeOutProc(fv,(PKmtVar)pv,cv); - break; - case PROTO_XM: - XTimeOutProc(fv,(PXVar)pv,cv); - break; - case PROTO_YM: - YTimeOutProc(fv,(PYVar)pv,cv); - break; - case PROTO_ZM: - ZTimeOutProc(fv,(PZVar)pv,cv); - break; - case PROTO_BP: - BPTimeOutProc(fv,(PBPVar)pv,cv); - break; - case PROTO_QV: - QVTimeOutProc(fv,(PQVVar)pv,cv); - break; - } -} - -BOOL FAR PASCAL ProtoCancel - (int Proto, PFileVar fv, PCHAR pv, PComVar cv) -{ - switch (Proto) { - case PROTO_KMT: - KmtCancel(fv,(PKmtVar)pv,cv); - break; - case PROTO_XM: - if (((PXVar)pv)->XMode==IdXReceive) - XCancel(fv,(PXVar)pv,cv); - break; - case PROTO_ZM: - ZCancel((PZVar)pv); - break; - case PROTO_BP: - if (((PBPVar)pv)->BPState != BP_Failure) - { - BPCancel((PBPVar)pv); - return FALSE; - } - break; - case PROTO_QV: - QVCancel(fv,(PQVVar)pv,cv); - break; - } - return TRUE; -} - -void FAR PASCAL TTFILESetUILanguageFile(char *file) -{ - strncpy_s(UILanguageFile, sizeof(UILanguageFile), file, _TRUNCATE); -} - -void FAR PASCAL TTFILESetFileSendFilter(char *file) -{ - strncpy_s(FileSendFilter, sizeof(FileSendFilter), file, _TRUNCATE); -} - -BOOL WINAPI DllMain(HANDLE hInstance, - ULONG ul_reason_for_call, - LPVOID lpReserved) -{ -// PMap pm; -// HANDLE HMap = NULL; - - hInst = hInstance; - switch( ul_reason_for_call ) { - case DLL_THREAD_ATTACH: - /* do thread initialization */ - break; - case DLL_THREAD_DETACH: - /* do thread cleanup */ - break; - case DLL_PROCESS_ATTACH: - /* do process initialization */ -// HMap = CreateFileMapping((HANDLE) 0xFFFFFFFF, NULL, PAGE_READONLY, -// 0, sizeof(TMap), TT_FILEMAPNAME); -// if (HMap != NULL) { -// pm = (PMap)MapViewOfFile(HMap,FILE_MAP_READ,0,0,0); -// if (pm != NULL) { -// strncpy_s(UILanguageFile, sizeof(UILanguageFile), pm->ts.UILanguageFile, _TRUNCATE); -// strncpy_s(FileSendFilter, sizeof(FileSendFilter), pm->ts.FileSendFilter, _TRUNCATE); -// } -// } - DoCover_IsDebuggerPresent(); - break; - case DLL_PROCESS_DETACH: - /* do process cleanup */ - break; - } - return TRUE; -} +/* Tera Term + Copyright(C) 1994-1998 T. Teranishi + All rights reserved. */ + +/* TTFILE.DLL, file transfer, VT window printing */ +#include "teraterm.h" +#include "tttypes.h" +#include "ttftypes.h" +#include <direct.h> +#include <commdlg.h> +#include <string.h> + +#include "ttlib.h" +#include "ftlib.h" +#include "dlglib.h" +#include "kermit.h" +#include "xmodem.h" +#include "ymodem.h" +#include "zmodem.h" +#include "bplus.h" +#include "quickvan.h" +// resource IDs +#include "file_res.h" + +#include <stdlib.h> +#include <stdio.h> +#include <io.h> + +#include "compat_w95.h" + +static HANDLE hInst; + +static HFONT DlgFoptFont; +static HFONT DlgXoptFont; +static HFONT DlgGetfnFont; + +char UILanguageFile[MAX_PATH]; +char FileSendFilter[128]; + +BOOL FAR PASCAL GetSetupFname(HWND HWin, WORD FuncId, PTTSet ts) +{ + int i, j; + OPENFILENAME ofn; + char uimsg[MAX_UIMSG]; + + // char FNameFilter[HostNameMaxLength + 1]; // 81(yutaka) + char FNameFilter[81]; // 81(yutaka) + char TempDir[MAXPATHLEN]; + char Dir[MAXPATHLEN]; + char Name[MAXPATHLEN]; + BOOL Ok; + + /* save current dir */ + _getcwd(TempDir,sizeof(TempDir)); + + /* File name filter */ + memset(FNameFilter, 0, sizeof(FNameFilter)); + if (FuncId==GSF_LOADKEY) + { + get_lang_msg("FILEDLG_KEYBOARD_FILTER", uimsg, sizeof(uimsg), "keyboard setup files (*.cnf)\\0*.cnf\\0\\0", UILanguageFile); + memcpy(FNameFilter, uimsg, sizeof(FNameFilter)); + } + else { + get_lang_msg("FILEDLG_SETUP_FILTER", uimsg, sizeof(uimsg), "setup files (*.ini)\\0*.ini\\0\\0", UILanguageFile); + memcpy(FNameFilter, uimsg, sizeof(FNameFilter)); + } + + /* OPENFILENAME record */ + memset(&ofn, 0, sizeof(OPENFILENAME)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = HWin; + ofn.lpstrFile = Name; + ofn.nMaxFile = sizeof(Name); + ofn.lpstrFilter = FNameFilter; + ofn.nFilterIndex = 1; + ofn.hInstance = hInst; + + if (FuncId==GSF_LOADKEY) + { + ofn.lpstrDefExt = "cnf"; + GetFileNamePos(ts->KeyCnfFN,&i,&j); + strncpy_s(Name, sizeof(Name),&(ts->KeyCnfFN[j]), _TRUNCATE); + memcpy(Dir,ts->KeyCnfFN,i); + Dir[i] = 0; + + if ((strlen(Name)==0) || (_stricmp(Name,"KEYBOARD.CNF")==0)) + strncpy_s(Name, sizeof(Name),"KEYBOARD.CNF", _TRUNCATE); + } + else { + ofn.lpstrDefExt = "ini"; + GetFileNamePos(ts->SetupFName,&i,&j); + strncpy_s(Name, sizeof(Name),&(ts->SetupFName[j]), _TRUNCATE); + memcpy(Dir,ts->SetupFName,i); + Dir[i] = 0; + + if ((strlen(Name)==0) || (_stricmp(Name,"TERATERM.INI")==0)) + strncpy_s(Name, sizeof(Name),"TERATERM.INI", _TRUNCATE); + } + + if (strlen(Dir)==0) + strncpy_s(Dir, sizeof(Dir),ts->HomeDir, _TRUNCATE); + + _chdir(Dir); + + ofn.Flags = OFN_SHOWHELP | OFN_HIDEREADONLY; + switch (FuncId) { + case GSF_SAVE: + // út@CfBNgðvO{̪ éÓÉÅè·é (2005.1.6 yutaka) + // ÇÝÜê½teraterm.iniª éfBNgÉÅè·éB + // ±êÉæèA/F= Åwè³ê½ÊuÉÛ¶³êéæ¤ÉÈéB(2005.1.26 yutaka) + // Windows Vista ÅÍt@C¼ÜÅwè·éÆ NULL Ư¶®ð·éæ¤ÈÌÅA + // t@C¼ðÜÜÈ¢`ÅfBNgðwè·éæ¤Éµ½B(2006.9.16 maya) +// ofn.lpstrInitialDir = __argv[0]; +// ofn.lpstrInitialDir = ts->SetupFName; + ofn.lpstrInitialDir = Dir; + get_lang_msg("FILEDLG_SAVE_SETUP_TITLE", uimsg, sizeof(uimsg), "Tera Term: Save setup", UILanguageFile); + ofn.lpstrTitle = uimsg; + Ok = GetSaveFileName(&ofn); + if (Ok) + strncpy_s(ts->SetupFName, sizeof(ts->SetupFName),Name, _TRUNCATE); + break; + case GSF_RESTORE: + ofn.Flags = ofn.Flags | OFN_FILEMUSTEXIST; + get_lang_msg("FILEDLG_RESTORE_SETUP_TITLE", uimsg, sizeof(uimsg), "Tera Term: Restore setup", UILanguageFile); + ofn.lpstrTitle = uimsg; + Ok = GetOpenFileName(&ofn); + if (Ok) + strncpy_s(ts->SetupFName, sizeof(ts->SetupFName),Name, _TRUNCATE); + break; + case GSF_LOADKEY: + ofn.Flags = ofn.Flags | OFN_FILEMUSTEXIST; + get_lang_msg("FILEDLG_LOAD_KEYMAP_TITLE", uimsg, sizeof(uimsg), "Tera Term: Load key map", UILanguageFile); + ofn.lpstrTitle = uimsg; + Ok = GetOpenFileName(&ofn); + if (Ok) + strncpy_s(ts->KeyCnfFN, sizeof(ts->KeyCnfFN),Name, _TRUNCATE); + break; + } + + /* restore dir */ + _chdir(TempDir); + + return Ok; +} + +/* Hook function for file name dialog box */ +BOOL CALLBACK TFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam) +{ + LPOPENFILENAME ofn; + WORD Lo, Hi; + LPLONG pl; + LPOFNOTIFY notify; + char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG]; + LOGFONT logfont; + HFONT font; + + switch (Message) { + case WM_INITDIALOG: + ofn = (LPOPENFILENAME)lParam; + pl = (LPLONG)(ofn->lCustData); + SetWindowLong(Dialog, DWL_USER, (LONG)pl); + + font = (HFONT)SendMessage(Dialog, WM_GETFONT, 0, 0); + GetObject(font, sizeof(LOGFONT), &logfont); + if (get_lang_font("DLG_TAHOMA_FONT", Dialog, &logfont, &DlgFoptFont, UILanguageFile)) { + SendDlgItemMessage(Dialog, IDC_FOPT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_FOPTBIN, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_FOPTAPPEND, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_PLAINTEXT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_TIMESTAMP, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_HIDEDIALOG, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + } + else { + DlgFoptFont = NULL; + } + + GetDlgItemText(Dialog, IDC_FOPT, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_FOPT", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_FOPT, uimsg); + GetDlgItemText(Dialog, IDC_FOPTBIN, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_FOPT_BINARY", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_FOPTBIN, uimsg); + GetDlgItemText(Dialog, IDC_FOPTAPPEND, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_FOPT_APPEND", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_FOPTAPPEND, uimsg); + GetDlgItemText(Dialog, IDC_PLAINTEXT, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_FOPT_PLAIN", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_PLAINTEXT, uimsg); + GetDlgItemText(Dialog, IDC_TIMESTAMP, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_FOPT_TIMESTAMP", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_TIMESTAMP, uimsg); + GetDlgItemText(Dialog, IDC_HIDEDIALOG, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_FOPT_HIDEDIALOG", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_HIDEDIALOG, uimsg); + + Lo = LOWORD(*pl) & 1; + Hi = HIWORD(*pl); + SetRB(Dialog,Lo,IDC_FOPTBIN,IDC_FOPTBIN); + if (Hi!=0xFFFF) + { + ShowDlgItem(Dialog,IDC_FOPTAPPEND,IDC_FOPTAPPEND); + SetRB(Dialog,Hi & 1,IDC_FOPTAPPEND,IDC_FOPTAPPEND); + + // plain text`FbN{bNXÍftHgÅON (2005.2.20 yutaka) + ShowDlgItem(Dialog,IDC_PLAINTEXT,IDC_PLAINTEXT); + if (Lo) { + // BinarytOªLøÈÆ«Í`FbNÅ«È¢ + DisableDlgItem(Dialog,IDC_PLAINTEXT,IDC_PLAINTEXT); + } + else if (Hi & 0x1000) { + SetRB(Dialog,1,IDC_PLAINTEXT,IDC_PLAINTEXT); + } + + // timestamp`FbN{bNX (2006.7.23 maya) + ShowDlgItem(Dialog,IDC_TIMESTAMP,IDC_TIMESTAMP); + if (Lo) { + // BinarytOªLøÈÆ«Í`FbNÅ«È¢ + DisableDlgItem(Dialog,IDC_TIMESTAMP,IDC_TIMESTAMP); + } + else if (Hi & 0x2000) { + SetRB(Dialog,1,IDC_TIMESTAMP,IDC_TIMESTAMP); + } + + // Hide dialog`FbN{bNX (2008.1.30 maya) + ShowDlgItem(Dialog,IDC_HIDEDIALOG,IDC_HIDEDIALOG); + if (Hi & 0x4000) { + SetRB(Dialog,1,IDC_HIDEDIALOG,IDC_HIDEDIALOG); + } + } + return TRUE; + + case WM_COMMAND: // for old style dialog + switch (LOWORD(wParam)) { + case IDOK: + pl = (LPLONG)GetWindowLong(Dialog,DWL_USER); + if (pl!=NULL) + { + GetRB(Dialog,&Lo,IDC_FOPTBIN,IDC_FOPTBIN); + Hi = HIWORD(*pl); + if (Hi!=0xFFFF) + GetRB(Dialog,&Hi,IDC_FOPTAPPEND,IDC_FOPTAPPEND); + *pl = MAKELONG(Lo,Hi); + } + break; + case IDCANCEL: + break; + case IDC_FOPTBIN: + GetRB(Dialog,&Lo,IDC_FOPTBIN,IDC_FOPTBIN); + if (Lo) { + DisableDlgItem(Dialog,IDC_PLAINTEXT,IDC_TIMESTAMP); + } + else { + EnableDlgItem(Dialog,IDC_PLAINTEXT,IDC_TIMESTAMP); + } + break; + } + break; + case WM_NOTIFY: // for Explorer-style dialog + notify = (LPOFNOTIFY)lParam; + switch (notify->hdr.code) { + case CDN_FILEOK: + pl = (LPLONG)GetWindowLong(Dialog,DWL_USER); + if (pl!=NULL) + { + WORD val = 0; + + GetRB(Dialog,&Lo,IDC_FOPTBIN,IDC_FOPTBIN); + Hi = HIWORD(*pl); + if (Hi!=0xFFFF) + GetRB(Dialog,&Hi,IDC_FOPTAPPEND,IDC_FOPTAPPEND); + + if (!Lo) { + // plain text check-box + GetRB(Dialog,&val,IDC_PLAINTEXT,IDC_PLAINTEXT); + if (val > 0) { // checked + Hi |= 0x1000; + } + + // timestamp`FbN{bNX (2006.7.23 maya) + GetRB(Dialog,&val,IDC_TIMESTAMP,IDC_TIMESTAMP); + if (val > 0) { + Hi |= 0x2000; + } + } + + // Hide dialog`FbN{bNX (2008.1.30 maya) + GetRB(Dialog,&val,IDC_HIDEDIALOG,IDC_HIDEDIALOG); + if (val > 0) { + Hi |= 0x4000; + } + + *pl = MAKELONG(Lo,Hi); + } + if (DlgFoptFont != NULL) { + DeleteObject(DlgFoptFont); + } + break; + } + break; + } + return FALSE; +} + +BOOL FAR PASCAL GetTransFname + (PFileVar fv, PCHAR CurDir, WORD FuncId, LPLONG Option) +{ + char uimsg[MAX_UIMSG]; + char FNFilter[sizeof(FileSendFilter)*3], *pf; + OPENFILENAME ofn; + LONG opt; + char TempDir[MAXPATHLEN]; + BOOL Ok; + char FileName[MAX_PATH]; + + /* save current dir */ + _getcwd(TempDir,sizeof(TempDir)); + + memset(FNFilter, 0, sizeof(FNFilter)); /* Set up for double null at end */ + memset(&ofn, 0, sizeof(OPENFILENAME)); + + strncpy_s(fv->DlgCaption, sizeof(fv->DlgCaption),"Tera Term: ", _TRUNCATE); + pf = FNFilter; + switch (FuncId) { + case GTF_SEND: + get_lang_msg("FILEDLG_TRANS_TITLE_SENDFILE", uimsg, sizeof(uimsg), TitSendFile, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + if (strlen(FileSendFilter) > 0) { + get_lang_msg("FILEDLG_USER_FILTER_NAME", uimsg, sizeof(uimsg), "User define", UILanguageFile); + _snprintf_s(FNFilter, sizeof(FNFilter), _TRUNCATE, "%s(%s)", uimsg, FileSendFilter); + pf = pf + strlen(FNFilter) + 1; + strncpy_s(pf, sizeof(FNFilter)-(pf - FNFilter) ,FileSendFilter, _TRUNCATE); + pf = pf + strlen(pf) + 1; + } + break; + case GTF_LOG: + get_lang_msg("FILEDLG_TRANS_TITLE_LOG", uimsg, sizeof(uimsg), TitLog, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case GTF_BP: + get_lang_msg("FILEDLG_TRANS_TITLE_BPSEND", uimsg, sizeof(uimsg), TitBPSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + if (strlen(FileSendFilter) > 0) { + get_lang_msg("FILEDLG_USER_FILTER_NAME", uimsg, sizeof(uimsg), "User define", UILanguageFile); + _snprintf_s(FNFilter, sizeof(FNFilter), _TRUNCATE, "%s(%s)", uimsg, FileSendFilter); + pf = pf + strlen(FNFilter) + 1; + strncpy_s(pf, sizeof(FNFilter)-(pf - FNFilter) ,FileSendFilter, _TRUNCATE); + pf = pf + strlen(pf) + 1; + } + break; + default: return FALSE; + } + + get_lang_msg("FILEDLG_ALL_FILTER", uimsg, sizeof(uimsg), "All(*.*)\\0*.*\\0\\0", UILanguageFile); + // \0\0 ÅIíéKvª éÌÅ 2 oCg + memcpy(pf, uimsg, sizeof(FNFilter) - (pf - FNFilter + 2)); + + ExtractFileName(fv->FullName, FileName ,sizeof(FileName)); + strncpy_s(fv->FullName, sizeof(fv->FullName), FileName, _TRUNCATE); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = fv->HMainWin; + ofn.lpstrFilter = FNFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = fv->FullName; + ofn.nMaxFile = sizeof(fv->FullName); + if (FuncId == GTF_LOG) { + DWORD logdir = GetFileAttributes(fv->LogDefaultPath); + // OÛ¶ÌêÍútH_ðßÅ¿µÈ¢æ¤É·éB(2007.8.24 yutaka) + if (logdir != -1 && logdir & FILE_ATTRIBUTE_DIRECTORY) { + // LogDefaultPathª¶Ý·éÈçA»±ðútH_É·éB(2007.11.30 maya) + ofn.lpstrInitialDir = fv->LogDefaultPath; + } + else { + ofn.lpstrInitialDir = NULL; + } + } else { + ofn.lpstrInitialDir = CurDir; + } + ofn.Flags = OFN_SHOWHELP | OFN_HIDEREADONLY; + if (FuncId!=GTF_BP) + { + ofn.Flags = ofn.Flags | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK; + ofn.Flags = ofn.Flags | OFN_EXPLORER; + ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FOPT); + ofn.lpfnHook = (LPOFNHOOKPROC)(&TFnHook); + } + opt = *Option; + if (FuncId!=GTF_LOG) + { + ofn.Flags = ofn.Flags | OFN_FILEMUSTEXIST; + opt = MAKELONG(LOWORD(*Option),0xFFFF); + + // tB^ªChJ[hÅÍÈA»Ìt@Cª¶Ý·éê + // 究ßftHgÌt@C¼ðüêĨ (2008.5.18 maya) + if (strlen(FileSendFilter) > 0 && + !isInvalidFileNameChar(FileSendFilter)) { + char file[MAX_PATH]; + strncpy_s(file, sizeof(file), CurDir, _TRUNCATE); + AppendSlash(file, sizeof(file)); + strncat_s(file, sizeof(file), FileSendFilter, _TRUNCATE); + if (_access(file, 0) == 0) { + strncpy_s(fv->FullName, sizeof(fv->FullName), FileSendFilter, _TRUNCATE); + } + } + } + ofn.lCustData = (DWORD)&opt; + ofn.lpstrTitle = fv->DlgCaption; + + ofn.hInstance = hInst; + + // loggingÌêAI[v_CAOðZ[u_CAOÖÏX (2005.1.6 yutaka) + if (FuncId == GTF_LOG) { + // OÌftHgl(log_YYYYMMDD_HHMMSS.txt)ðÝè·é (2005.1.21 yutaka) + // ftHgt@C¼ð teraterm.log ÖÏX (2005.2.22 yutaka) + // ftHgt@C¼ÌÝèêðÄÑoµ³ÖÚ® (2006.8.28 maya) + Ok = GetSaveFileName(&ofn); + } else { + Ok = GetOpenFileName(&ofn); + } + + if (Ok) + { + if (FuncId==GTF_LOG) + *Option = opt; + else + *Option = MAKELONG(LOWORD(opt),HIWORD(*Option)); + + fv->DirLen = ofn.nFileOffset; + + if (CurDir!=NULL) + { + memcpy(CurDir,fv->FullName,fv->DirLen-1); + CurDir[fv->DirLen-1] = 0; + } + } + /* restore dir */ + _chdir(TempDir); + return Ok; +} + +BOOL CALLBACK TFn2Hook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam) +{ + LPOPENFILENAME ofn; + LPWORD pw; + LPOFNOTIFY notify; + char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG]; + LOGFONT logfont; + HFONT font; + + switch (Message) { + case WM_INITDIALOG: + ofn = (LPOPENFILENAME)lParam; + pw = (LPWORD)ofn->lCustData; + SetWindowLong(Dialog, DWL_USER, (LONG)pw); + + font = (HFONT)SendMessage(Dialog, WM_GETFONT, 0, 0); + GetObject(font, sizeof(LOGFONT), &logfont); + if (get_lang_font("DLG_TAHOMA_FONT", Dialog, &logfont, &DlgFoptFont, UILanguageFile)) { + SendDlgItemMessage(Dialog, IDC_FOPT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_FOPTBIN, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_FOPTAPPEND, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_PLAINTEXT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_TIMESTAMP, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + } + else { + DlgFoptFont = NULL; + } + + GetDlgItemText(Dialog, IDC_FOPT, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_FOPT", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_FOPT, uimsg); + GetDlgItemText(Dialog, IDC_FOPTBIN, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_FOPT_BINARY", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_FOPTBIN, uimsg); + + SetRB(Dialog,*pw & 1,IDC_FOPTBIN,IDC_FOPTBIN); + return TRUE; + case WM_COMMAND: // for old style dialog + switch (LOWORD(wParam)) { + case IDOK: + pw = (LPWORD)GetWindowLong(Dialog,DWL_USER); + if (pw!=NULL) + GetRB(Dialog,pw,IDC_FOPTBIN,IDC_FOPTBIN); + break; + case IDCANCEL: + break; + } + break; + case WM_NOTIFY: // for Explorer-style dialog + notify = (LPOFNOTIFY)lParam; + switch (notify->hdr.code) { + case CDN_FILEOK: + pw = (LPWORD)GetWindowLong(Dialog,DWL_USER); + if (pw!=NULL) + GetRB(Dialog,pw,IDC_FOPTBIN,IDC_FOPTBIN); + if (DlgFoptFont != NULL) { + DeleteObject(DlgFoptFont); + } + break; + } + break; + } + return FALSE; +} + +BOOL FAR PASCAL GetMultiFname + (PFileVar fv, PCHAR CurDir, WORD FuncId, LPWORD Option) +{ + int i, len; + char uimsg[MAX_UIMSG]; + char FNFilter[sizeof(FileSendFilter)*2+128], *pf; + OPENFILENAME ofn; + char TempDir[MAXPATHLEN]; + BOOL Ok; + char defaultFName[MAX_PATH]; + + memset(FNFilter, 0, sizeof(FNFilter)); /* Set up for double null at end */ + + /* save current dir */ + _getcwd(TempDir,sizeof(TempDir)); + + fv->NumFname = 0; + + strncpy_s(fv->DlgCaption, sizeof(fv->DlgCaption),"Tera Term: ", _TRUNCATE); + pf = FNFilter; + switch (FuncId) { + case GMF_KERMIT: + get_lang_msg("FILEDLG_TRANS_TITLE_KMTSEND", uimsg, sizeof(uimsg), TitKmtSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case GMF_Z: + get_lang_msg("FILEDLG_TRANS_TITLE_ZSEND", uimsg, sizeof(uimsg), TitZSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case GMF_QV: + get_lang_msg("FILEDLG_TRANS_TITLE_QVSEND", uimsg, sizeof(uimsg), TitQVSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case GMF_Y: + get_lang_msg("FILEDLG_TRANS_TITLE_YSEND", uimsg, sizeof(uimsg), TitYSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + default: + return FALSE; + } + if (strlen(FileSendFilter) > 0) { + get_lang_msg("FILEDLG_USER_FILTER_NAME", uimsg, sizeof(uimsg), "User define", UILanguageFile); + _snprintf_s(FNFilter, sizeof(FNFilter), _TRUNCATE, "%s(%s)", uimsg, FileSendFilter); + pf = pf + strlen(FNFilter) + 1; + strncpy_s(pf, sizeof(FNFilter)-(pf - FNFilter) ,FileSendFilter, _TRUNCATE); + pf = pf + strlen(pf) + 1; + } + + /* moemory should be zero-initialized */ + fv->FnStrMemHandle = GlobalAlloc(GHND, FnStrMemSize); + if (fv->FnStrMemHandle == NULL) + { + MessageBeep(0); + return FALSE; + } + else { + fv->FnStrMem = GlobalLock(fv->FnStrMemHandle); + if (fv->FnStrMem == NULL) + { + GlobalFree(fv->FnStrMemHandle); + fv->FnStrMemHandle = 0; + MessageBeep(0); + return FALSE; + } + } + + get_lang_msg("FILEDLG_ALL_FILTER", uimsg, sizeof(uimsg), "All(*.*)\\0*.*\\0\\0", UILanguageFile); + // \0\0 ÅIíéKvª éÌÅ 2 oCg + memcpy(pf, uimsg, sizeof(FNFilter) - (pf - FNFilter + 2)); + + memset(&ofn, 0, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = fv->HMainWin; + ofn.lpstrFilter = FNFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = fv->FnStrMem; + ofn.nMaxFile = FnStrMemSize; + ofn.lpstrTitle= fv->DlgCaption; + ofn.lpstrInitialDir = CurDir; + ofn.Flags = OFN_SHOWHELP | OFN_ALLOWMULTISELECT | + OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + ofn.Flags = ofn.Flags | OFN_EXPLORER; + ofn.lCustData = 0; + if (FuncId==GMF_Z) + { + ofn.Flags = ofn.Flags | OFN_ENABLETEMPLATE | OFN_ENABLEHOOK; + ofn.lCustData = (DWORD)Option; + ofn.lpfnHook = (LPOFNHOOKPROC)(&TFn2Hook); + ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FOPT); + } else if (FuncId==GMF_Y) { + // TODO: YMODEM + + } + + ofn.hInstance = hInst; + + // tB^ªChJ[hÅÍÈA»Ìt@Cª¶Ý·éê + // 究ßftHgÌt@C¼ðüêĨ (2008.5.18 maya) + if (strlen(FileSendFilter) > 0 && + !isInvalidFileNameChar(FileSendFilter)) { + char file[MAX_PATH]; + strncpy_s(file, sizeof(file), CurDir, _TRUNCATE); + AppendSlash(file, sizeof(file)); + strncat_s(file, sizeof(file), FileSendFilter, _TRUNCATE); + if (_access(file, 0) == 0) { + strncpy_s(defaultFName, sizeof(defaultFName), FileSendFilter, _TRUNCATE); + ofn.lpstrFile = defaultFName; + } + } + + Ok = GetOpenFileName(&ofn); + if (Ok) + { + /* count number of file names */ + len = strlen(fv->FnStrMem); + i = 0; + while (len>0) + { + i = i + len + 1; + fv->NumFname++; + len = strlen(&fv->FnStrMem[i]); + } + + fv->NumFname--; + + if (fv->NumFname<1) + { // single selection + fv->NumFname = 1; + fv->DirLen = ofn.nFileOffset; + strncpy_s(fv->FullName, sizeof(fv->FullName),fv->FnStrMem, _TRUNCATE); + fv->FnPtr = 0; + } + else { // multiple selection + strncpy_s(fv->FullName, sizeof(fv->FullName),fv->FnStrMem, _TRUNCATE); + AppendSlash(fv->FullName,sizeof(fv->FullName)); + fv->DirLen = strlen(fv->FullName); + fv->FnPtr = strlen(fv->FnStrMem)+1; + } + + memcpy(CurDir,fv->FullName,fv->DirLen); + CurDir[fv->DirLen] = 0; + if ((fv->DirLen>3) && + (CurDir[fv->DirLen-1]=='\\')) + CurDir[fv->DirLen-1] = 0; + + fv->FNCount = 0; + } + + GlobalUnlock(fv->FnStrMemHandle); + if (! Ok) + { + GlobalFree(fv->FnStrMemHandle); + fv->FnStrMemHandle = NULL; + } + + /* restore dir */ + _chdir(TempDir); + + return Ok; +} + +BOOL CALLBACK GetFnDlg + (HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam) +{ + PFileVar fv; + char TempFull[MAXPATHLEN]; + int i, j; + char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG]; + LOGFONT logfont; + HFONT font; + + switch (Message) { + case WM_INITDIALOG: + fv = (PFileVar)lParam; + SetWindowLong(Dialog, DWL_USER, lParam); + SendDlgItemMessage(Dialog, IDC_GETFN, EM_LIMITTEXT, sizeof(TempFull)-1,0); + + font = (HFONT)SendMessage(Dialog, WM_GETFONT, 0, 0); + GetObject(font, sizeof(LOGFONT), &logfont); + if (get_lang_font("DLG_SYSTEM_FONT", Dialog, &logfont, &DlgGetfnFont, UILanguageFile)) { + SendDlgItemMessage(Dialog, IDC_FILENAME, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_GETFN, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDOK, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDCANCEL, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_GETFNHELP, WM_SETFONT, (WPARAM)DlgGetfnFont, MAKELPARAM(TRUE,0)); + } + else { + DlgGetfnFont = NULL; + } + + GetWindowText(Dialog, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_GETFN_TITLE", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetWindowText(Dialog, uimsg); + GetDlgItemText(Dialog, IDC_FILENAME, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_GETFN_FILENAME", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_FILENAME, uimsg); + GetDlgItemText(Dialog, IDOK, uimsg2, sizeof(uimsg2)); + get_lang_msg("BTN_OK", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDOK, uimsg); + GetDlgItemText(Dialog, IDCANCEL, uimsg2, sizeof(uimsg2)); + get_lang_msg("BTN_CANCEL", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDCANCEL, uimsg); + GetDlgItemText(Dialog, IDC_GETFNHELP, uimsg2, sizeof(uimsg2)); + get_lang_msg("BTN_HELP", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_GETFNHELP, uimsg); + + return TRUE; + + case WM_COMMAND: + fv = (PFileVar)GetWindowLong(Dialog,DWL_USER); + switch (LOWORD(wParam)) { + case IDOK: + if (fv!=NULL) + { + GetDlgItemText(Dialog, IDC_GETFN, TempFull, sizeof(TempFull)); + if (strlen(TempFull)==0) return TRUE; + GetFileNamePos(TempFull,&i,&j); + FitFileName(&(TempFull[j]),sizeof(TempFull) - j, NULL); + strncat_s(fv->FullName,sizeof(fv->FullName),&(TempFull[j]),_TRUNCATE); + } + EndDialog(Dialog, 1); + if (DlgGetfnFont != NULL) { + DeleteObject(DlgGetfnFont); + } + return TRUE; + case IDCANCEL: + EndDialog(Dialog, 0); + if (DlgGetfnFont != NULL) { + DeleteObject(DlgGetfnFont); + } + return TRUE; + case IDC_GETFNHELP: + if (fv!=NULL) + PostMessage(fv->HMainWin,WM_USER_DLGHELP2,0,0); + break; + } + } + return FALSE; +} + +BOOL FAR PASCAL GetGetFname(HWND HWin, PFileVar fv) +{ + return (BOOL)DialogBoxParam(hInst, + MAKEINTRESOURCE(IDD_GETFNDLG), + HWin, GetFnDlg, (LONG)fv); +} + +void FAR PASCAL SetFileVar(PFileVar fv) +{ + int i; + char uimsg[MAX_UIMSG]; + + GetFileNamePos(fv->FullName,&(fv->DirLen),&i); + if (fv->FullName[fv->DirLen]=='\\') fv->DirLen++; + strncpy_s(fv->DlgCaption, sizeof(fv->DlgCaption),"Tera Term: ", _TRUNCATE); + switch (fv->OpId) { + case OpLog: + get_lang_msg("FILEDLG_TRANS_TITLE_LOG", uimsg, sizeof(uimsg), TitLog, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpSendFile: + get_lang_msg("FILEDLG_TRANS_TITLE_SENDFILE", uimsg, sizeof(uimsg), TitSendFile, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpKmtRcv: + get_lang_msg("FILEDLG_TRANS_TITLE_KMTRCV", uimsg, sizeof(uimsg), TitKmtRcv, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpKmtGet: + get_lang_msg("FILEDLG_TRANS_TITLE_KMTGET", uimsg, sizeof(uimsg), TitKmtGet, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpKmtSend: + get_lang_msg("FILEDLG_TRANS_TITLE_KMTSEND", uimsg, sizeof(uimsg), TitKmtSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpKmtFin: + get_lang_msg("FILEDLG_TRANS_TITLE_KMTFIN", uimsg, sizeof(uimsg), TitKmtFin, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpXRcv: + get_lang_msg("FILEDLG_TRANS_TITLE_XRCV", uimsg, sizeof(uimsg), TitXRcv, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpXSend: + get_lang_msg("FILEDLG_TRANS_TITLE_XSEND", uimsg, sizeof(uimsg), TitXSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpYRcv: + get_lang_msg("FILEDLG_TRANS_TITLE_YRCV", uimsg, sizeof(uimsg), TitYRcv, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpYSend: + get_lang_msg("FILEDLG_TRANS_TITLE_YSEND", uimsg, sizeof(uimsg), TitYSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpZRcv: + get_lang_msg("FILEDLG_TRANS_TITLE_ZRCV", uimsg, sizeof(uimsg), TitZRcv, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpZSend: + get_lang_msg("FILEDLG_TRANS_TITLE_ZSEND", uimsg, sizeof(uimsg), TitZSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpBPRcv: + get_lang_msg("FILEDLG_TRANS_TITLE_BPRCV", uimsg, sizeof(uimsg), TitBPRcv, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpBPSend: + get_lang_msg("FILEDLG_TRANS_TITLE_BPSEND", uimsg, sizeof(uimsg), TitBPSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpQVRcv: + get_lang_msg("FILEDLG_TRANS_TITLE_QVRCV", uimsg, sizeof(uimsg), TitQVRcv, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + case OpQVSend: + get_lang_msg("FILEDLG_TRANS_TITLE_QVSEND", uimsg, sizeof(uimsg), TitQVSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + break; + } +} + +/* Hook function for XMODEM file name dialog box */ +BOOL CALLBACK XFnHook(HWND Dialog, UINT Message, WPARAM wParam, LPARAM lParam) +{ + LPOPENFILENAME ofn; + WORD Hi, Lo; + LPLONG pl; + LPOFNOTIFY notify; + char uimsg[MAX_UIMSG], uimsg2[MAX_UIMSG]; + LOGFONT logfont; + HFONT font; + + switch (Message) { + case WM_INITDIALOG: + ofn = (LPOPENFILENAME)lParam; + pl = (LPLONG)ofn->lCustData; + SetWindowLong(Dialog, DWL_USER, (LONG)pl); + + font = (HFONT)SendMessage(Dialog, WM_GETFONT, 0, 0); + GetObject(font, sizeof(LOGFONT), &logfont); + if (get_lang_font("DLG_TAHOMA_FONT", Dialog, &logfont, &DlgFoptFont, UILanguageFile)) { + SendDlgItemMessage(Dialog, IDC_XOPT, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_XOPTCHECK, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_XOPTCRC, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_XOPT1K, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + SendDlgItemMessage(Dialog, IDC_XOPTBIN, WM_SETFONT, (WPARAM)DlgFoptFont, MAKELPARAM(TRUE,0)); + } + else { + DlgFoptFont = NULL; + } + + GetDlgItemText(Dialog, IDC_XOPT, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_XOPT", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_XOPT, uimsg); + GetDlgItemText(Dialog, IDC_XOPTCHECK, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_XOPT_CHECKSUM", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_XOPTCHECK, uimsg); + GetDlgItemText(Dialog, IDC_XOPTCRC, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_XOPT_CRC", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_XOPTCRC, uimsg); + GetDlgItemText(Dialog, IDC_XOPT1K, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_XOPT_1K", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_XOPT1K, uimsg); + GetDlgItemText(Dialog, IDC_XOPTBIN, uimsg2, sizeof(uimsg2)); + get_lang_msg("DLG_XOPT_BINARY", uimsg, sizeof(uimsg), uimsg2, UILanguageFile); + SetDlgItemText(Dialog, IDC_XOPTBIN, uimsg); + + SetRB(Dialog,HIWORD(*pl),IDC_XOPTCHECK,IDC_XOPT1K); + if (LOWORD(*pl)!=0xFFFF) + { + ShowDlgItem(Dialog,IDC_XOPTBIN,IDC_XOPTBIN); + SetRB(Dialog,LOWORD(*pl),IDC_XOPTBIN,IDC_XOPTBIN); + } + return TRUE; + case WM_COMMAND: // for old style dialog + switch (LOWORD(wParam)) { + case IDOK: + pl = (LPLONG)GetWindowLong(Dialog,DWL_USER); + if (pl!=NULL) + { + GetRB(Dialog,&Hi,IDC_XOPTCHECK,IDC_XOPT1K); + if (LOWORD(*pl)==0xFFFF) + Lo = 0xFFFF; + else + GetRB(Dialog,&Lo,IDC_XOPTBIN,IDC_XOPTBIN); + *pl = MAKELONG(Lo,Hi); + } + break; + case IDCANCEL: + break; + } + break; + case WM_NOTIFY: // for Explorer-style dialog + notify = (LPOFNOTIFY)lParam; + switch (notify->hdr.code) { + case CDN_FILEOK: + pl = (LPLONG)GetWindowLong(Dialog,DWL_USER); + if (pl!=NULL) + { + GetRB(Dialog,&Hi,IDC_XOPTCHECK,IDC_XOPT1K); + if (LOWORD(*pl)==0xFFFF) + Lo = 0xFFFF; + else + GetRB(Dialog,&Lo,IDC_XOPTBIN,IDC_XOPTBIN); + *pl = MAKELONG(Lo,Hi); + } + if (DlgXoptFont != NULL) { + DeleteObject(DlgXoptFont); + } + break; + } + break; + } + return FALSE; +} + +BOOL FAR PASCAL GetXFname + (HWND HWin, BOOL Receive, LPLONG Option, PFileVar fv, PCHAR CurDir) +{ + char uimsg[MAX_UIMSG]; + char FNFilter[sizeof(FileSendFilter)*2+128], *pf; + OPENFILENAME ofn; + LONG opt; + char TempDir[MAXPATHLEN]; + BOOL Ok; + + memset(FNFilter, 0, sizeof(FNFilter)); /* Set up for double null at end */ + + /* save current dir */ + _getcwd(TempDir,sizeof(TempDir)); + + fv->FullName[0] = 0; + memset(FNFilter, 0, sizeof(FNFilter)); /* Set up for double null at end */ + memset(&ofn, 0, sizeof(OPENFILENAME)); + + strncpy_s(fv->DlgCaption, sizeof(fv->DlgCaption),"Tera Term: ", _TRUNCATE); + pf = FNFilter; + if (Receive) + { + get_lang_msg("FILEDLG_TRANS_TITLE_XRCV", uimsg, sizeof(uimsg), TitXRcv, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + } + else + { + get_lang_msg("FILEDLG_TRANS_TITLE_XSEND", uimsg, sizeof(uimsg), TitXSend, UILanguageFile); + strncat_s(fv->DlgCaption, sizeof(fv->DlgCaption), uimsg, _TRUNCATE); + if (strlen(FileSendFilter) > 0) { + get_lang_msg("FILEDLG_USER_FILTER_NAME", uimsg, sizeof(uimsg), "User define", UILanguageFile); + _snprintf_s(FNFilter, sizeof(FNFilter), _TRUNCATE, "%s(%s)", uimsg, FileSendFilter); + pf = pf + strlen(FNFilter) + 1; + strncpy_s(pf, sizeof(FNFilter)-(pf - FNFilter) ,FileSendFilter, _TRUNCATE); + pf = pf + strlen(pf) + 1; + + // tB^ªChJ[hÅÍÈA»Ìt@Cª¶Ý·éê + // 究ßftHgÌt@C¼ðüêĨ (2008.5.18 maya) + if (!isInvalidFileNameChar(FileSendFilter)) { + char file[MAX_PATH]; + strncpy_s(file, sizeof(file), CurDir, _TRUNCATE); + AppendSlash(file, sizeof(file)); + strncat_s(file, sizeof(file), FileSendFilter, _TRUNCATE); + if (_access(file, 0) == 0) { + strncpy_s(fv->FullName, sizeof(fv->FullName), FileSendFilter, _TRUNCATE); + } + } + } + } + + get_lang_msg("FILEDLG_ALL_FILTER", uimsg, sizeof(uimsg), "All(*.*)\\0*.*\\0\\0", UILanguageFile); + // \0\0 ÅIíéKvª éÌÅ 2 oCg + memcpy(pf, uimsg, sizeof(FNFilter) - (pf - FNFilter + 2)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = HWin; + ofn.lpstrFilter = FNFilter; + ofn.nFilterIndex = 1; + ofn.lpstrFile = fv->FullName; + ofn.nMaxFile = sizeof(fv->FullName); + ofn.lpstrInitialDir = CurDir; + ofn.Flags = OFN_SHOWHELP | OFN_HIDEREADONLY | + OFN_ENABLETEMPLATE | OFN_ENABLEHOOK; + opt = *Option; + if (! Receive) + { + ofn.Flags = ofn.Flags | OFN_FILEMUSTEXIST; + opt = opt | 0xFFFF; + } + ofn.lCustData = (DWORD)&opt; + + ofn.lpstrTitle = fv->DlgCaption; + ofn.lpfnHook = (LPOFNHOOKPROC)(&XFnHook); + ofn.Flags = ofn.Flags | OFN_EXPLORER; + ofn.lpTemplateName = MAKEINTRESOURCE(IDD_XOPT); + ofn.hInstance = hInst; + + Ok = GetOpenFileName(&ofn); + + if (Ok) + { + fv->DirLen = ofn.nFileOffset; + fv->FnPtr = ofn.nFileOffset; + memcpy(CurDir,fv->FullName,fv->DirLen-1); + CurDir[fv->DirLen-1] = 0; + + if (Receive) + *Option = opt; + else + *Option = MAKELONG(LOWORD(*Option),HIWORD(opt)); + } + + /* restore dir */ + _chdir(TempDir); + + return Ok; +} + +void FAR PASCAL ProtoInit(int Proto, PFileVar fv, PCHAR pv, PComVar cv, PTTSet ts) +{ + switch (Proto) { + case PROTO_KMT: + KmtInit(fv,(PKmtVar)pv,cv,ts); + break; + case PROTO_XM: + XInit(fv,(PXVar)pv,cv,ts); + break; + case PROTO_YM: + YInit(fv,(PYVar)pv,cv,ts); + break; + case PROTO_ZM: + ZInit(fv,(PZVar)pv,cv,ts); + break; + case PROTO_BP: + BPInit(fv,(PBPVar)pv,cv,ts); + break; + case PROTO_QV: + QVInit(fv,(PQVVar)pv,cv,ts); + break; + } +} + +BOOL FAR PASCAL ProtoParse + (int Proto, PFileVar fv, PCHAR pv, PComVar cv) +{ + BOOL Ok; + + Ok = FALSE; + switch (Proto) { + case PROTO_KMT: + Ok = KmtReadPacket(fv,(PKmtVar)pv,cv); + break; + case PROTO_XM: + switch (((PXVar)pv)->XMode) { + case IdXReceive: + Ok = XReadPacket(fv,(PXVar)pv,cv); + break; + case IdXSend: + Ok = XSendPacket(fv,(PXVar)pv,cv); + break; + } + break; + case PROTO_YM: + switch (((PYVar)pv)->YMode) { + case IdYReceive: + Ok = YReadPacket(fv,(PYVar)pv,cv); + break; + case IdYSend: + Ok = YSendPacket(fv,(PYVar)pv,cv); + break; + } + break; + case PROTO_ZM: + Ok = ZParse(fv,(PZVar)pv,cv); + break; + case PROTO_BP: + Ok = BPParse(fv,(PBPVar)pv,cv); + break; + case PROTO_QV: + switch (((PQVVar)pv)->QVMode) { + case IdQVReceive: + Ok = QVReadPacket(fv,(PQVVar)pv,cv); + break; + case IdQVSend: + Ok = QVSendPacket(fv,(PQVVar)pv,cv); + break; + } + break; + } + return Ok; +} + +void FAR PASCAL ProtoTimeOutProc + (int Proto, PFileVar fv, PCHAR pv, PComVar cv) +{ + switch (Proto) { + case PROTO_KMT: + KmtTimeOutProc(fv,(PKmtVar)pv,cv); + break; + case PROTO_XM: + XTimeOutProc(fv,(PXVar)pv,cv); + break; + case PROTO_YM: + YTimeOutProc(fv,(PYVar)pv,cv); + break; + case PROTO_ZM: + ZTimeOutProc(fv,(PZVar)pv,cv); + break; + case PROTO_BP: + BPTimeOutProc(fv,(PBPVar)pv,cv); + break; + case PROTO_QV: + QVTimeOutProc(fv,(PQVVar)pv,cv); + break; + } +} + +BOOL FAR PASCAL ProtoCancel + (int Proto, PFileVar fv, PCHAR pv, PComVar cv) +{ + switch (Proto) { + case PROTO_KMT: + KmtCancel(fv,(PKmtVar)pv,cv); + break; + case PROTO_XM: + XCancel(fv,(PXVar)pv,cv); + break; + case PROTO_YM: + YCancel(fv, (PYVar)pv,cv); + break; + case PROTO_ZM: + ZCancel((PZVar)pv); + break; + case PROTO_BP: + if (((PBPVar)pv)->BPState != BP_Failure) + { + BPCancel((PBPVar)pv); + return FALSE; + } + break; + case PROTO_QV: + QVCancel(fv,(PQVVar)pv,cv); + break; + } + return TRUE; +} + +void FAR PASCAL TTFILESetUILanguageFile(char *file) +{ + strncpy_s(UILanguageFile, sizeof(UILanguageFile), file, _TRUNCATE); +} + +void FAR PASCAL TTFILESetFileSendFilter(char *file) +{ + strncpy_s(FileSendFilter, sizeof(FileSendFilter), file, _TRUNCATE); +} + +BOOL WINAPI DllMain(HANDLE hInstance, + ULONG ul_reason_for_call, + LPVOID lpReserved) +{ +// PMap pm; +// HANDLE HMap = NULL; + + hInst = hInstance; + switch( ul_reason_for_call ) { + case DLL_THREAD_ATTACH: + /* do thread initialization */ + break; + case DLL_THREAD_DETACH: + /* do thread cleanup */ + break; + case DLL_PROCESS_ATTACH: + /* do process initialization */ +// HMap = CreateFileMapping((HANDLE) 0xFFFFFFFF, NULL, PAGE_READONLY, +// 0, sizeof(TMap), TT_FILEMAPNAME); +// if (HMap != NULL) { +// pm = (PMap)MapViewOfFile(HMap,FILE_MAP_READ,0,0,0); +// if (pm != NULL) { +// strncpy_s(UILanguageFile, sizeof(UILanguageFile), pm->ts.UILanguageFile, _TRUNCATE); +// strncpy_s(FileSendFilter, sizeof(FileSendFilter), pm->ts.FileSendFilter, _TRUNCATE); +// } +// } + DoCover_IsDebuggerPresent(); + break; + case DLL_PROCESS_DETACH: + /* do process cleanup */ + break; + } + return TRUE; +} Modified: trunk/teraterm/ttpfile/xmodem.c =================================================================== --- trunk/teraterm/ttpfile/xmodem.c 2010-04-12 12:51:24 UTC (rev 3854) +++ trunk/teraterm/ttpfile/xmodem.c 2010-04-12 13:43:07 UTC (rev 3855) @@ -1,505 +1,505 @@ -/* Tera Term - Copyright(C) 1994-1998 T. Teranishi - All rights reserved. */ - -/* TTFILE.DLL, XMODEM protocol */ -#include "teraterm.h" -#include "tttypes.h" -#include "ttftypes.h" -#include <stdio.h> - -#include "tt_res.h" -#include "ttcommon.h" -#include "ttlib.h" -#include "ftlib.h" -#include "dlglib.h" - -#include "xmodem.h" - -#define TimeOutInit 10 -#define TimeOutC 3 -#define TimeOutShort 10 -#define TimeOutLong 20 -#define TimeOutVeryLong 60 - -int XRead1Byte(PFileVar fv, PXVar xv, PComVar cv, LPBYTE b) -{ - if (CommRead1Byte(cv, b) == 0) - return 0; - - if (fv->LogFlag) { - if (fv->LogState == 0) { - // cèÌASCII\¦ðs¤ - fv->FlushLogLineBuf = 1; - FTLog1Byte(fv, 0); - fv->FlushLogLineBuf = 0; - - fv->LogState = 1; - fv->LogCount = 0; - _lwrite(fv->LogFile, "\015\012<<<\015\012", 7); - } - FTLog1Byte(fv, *b); - } - return 1; -} - -int XWrite(PFileVar fv, PXVar xv, PComVar cv, PCHAR B, int C) -{ - int i, j; - - i = CommBinaryOut(cv, B, C); - if (fv->LogFlag && (i > 0)) { - if (fv->LogState != 0) { - // cèÌASCII\¦ðs¤ - fv->FlushLogLineBuf = 1; - FTLog1Byte(fv, 0); - fv->FlushLogLineBuf = 0; - - fv->LogState = 0; - fv->LogCount = 0; - _lwrite(fv->LogFile, "\015\012>>>\015\012", 7); - } - for (j = 0; j <= i - 1; j++) - FTLog1Byte(fv, B[j]); - } - return i; -} - -void XSetOpt(PFileVar fv, PXVar xv, WORD Opt) -{ - char Tmp[21]; - - xv->XOpt = Opt; - - strncpy_s(Tmp, sizeof(Tmp), "XMODEM (", _TRUNCATE); - switch (xv->XOpt) { - case XoptCheck: /* Checksum */ - strncat_s(Tmp, sizeof(Tmp), "checksum)", _TRUNCATE); - xv->DataLen = 128; - xv->CheckLen = 1; - break; - case XoptCRC: /* CRC */ - strncat_s(Tmp, sizeof(Tmp), "CRC)", _TRUNCATE); - xv->DataLen = 128; - xv->CheckLen = 2; - break; - case Xopt1K: /* 1K */ - strncat_s(Tmp, sizeof(Tmp), "1K)", _TRUNCATE); - xv->DataLen = 1024; - xv->CheckLen = 2; - break; - } - SetDlgItemText(fv->HWin, IDC_PROTOPROT, Tmp); -} - -void XSendNAK(PFileVar fv, PXVar xv, PComVar cv) -{ - BYTE b; - int t; - - /* flush comm buffer */ - cv->InBuffCount = 0; - cv->InPtr = 0; - - xv->NAKCount--; - if (xv->NAKCount < 0) { - if (xv->NAKMode == XnakC) { - XSetOpt(fv, xv, XoptCheck); - xv->NAKMode = XnakNAK; - xv->NAKCount = 9; - } else { - XCancel(fv, xv, cv); - return; - } - } - - if (xv->NAKMode == XnakNAK) { - b = NAK; - if ((xv->PktNum == 0) && (xv->PktNumOffset == 0)) - t = TimeOutInit; - else - t = xv->TOutLong; - } else { - b = 'C'; - t = TimeOutC; - } - XWrite(fv, xv, cv, &b, 1); - xv->PktReadMode = XpktSOH; - FTSetTimeOut(fv, t); -} - -WORD XCalcCheck(PXVar xv, PCHAR PktBuf) -{ - int i; - WORD Check; - - if (xv->CheckLen == 1) { /* CheckSum */ - /* Calc sum */ - Check = 0; - for (i = 0; i <= xv->DataLen - 1; i++) - Check = Check + (BYTE) (PktBuf[3 + i]); - return (Check & 0xff); - } else { /* CRC */ - Check = 0; - for (i = 0; i <= xv->DataLen - 1; i++) - Check = UpdateCRC(PktBuf[3 + i], Check); - return (Check); - } -} - -BOOL XCheckPacket(PXVar xv) -{ - WORD Check; - - Check = XCalcCheck(xv, xv->PktIn); - if (xv->CheckLen == 1) /* Checksum */ - return ((BYTE) Check == xv->PktIn[xv->DataLen + 3]); - else - return ((HIBYTE(Check) == xv->PktIn[xv->DataLen + 3]) && - (LOBYTE(Check) == xv->PktIn[xv->DataLen + 4])); -} - -void XInit(PFileVar fv, PXVar xv, PComVar cv, PTTSet ts) { - char inistr[MAXPATHLEN + 10]; - - fv->LogFlag = ((ts->LogFlag & LOG_X) != 0); - if (fv->LogFlag) - fv->LogFile = _lcreat("XMODEM.LOG", 0); - fv->LogState = 0; - fv->LogCount = 0; - - fv->FileSize = 0; - if ((xv->XMode == IdXSend) && fv->FileOpen) { - fv->FileSize = GetFSize(fv->FullName); - InitDlgProgress(fv->HWin, IDC_PROTOPROGRESS, &fv->ProgStat); - } else { - fv->ProgStat = -1; - } - - SetWindowText(fv->HWin, fv->DlgCaption); - SetDlgItemText(fv->HWin, IDC_PROTOFNAME, &(fv->FullName[fv->DirLen])); - - xv->PktNumOffset = 0; - xv->PktNum = 0; - xv->PktNumSent = 0; - xv->PktBufCount = 0; - xv->CRRecv = FALSE; - - fv->ByteCount = 0; - - if (cv->PortType == IdTCPIP) { - xv->TOutShort = TimeOutVeryLong; - xv->TOutLong = TimeOutVeryLong; - } else { - xv->TOutShort = TimeOutShort; - xv->TOutLong = TimeOutLong; - } - - XSetOpt(fv, xv, xv->XOpt); - - if (xv->XOpt == XoptCheck) { - xv->NAKMode = XnakNAK; - xv->NAKCount = 10; - } else { - xv->NAKMode = XnakC; - xv->NAKCount = 3; - } - - switch (xv->XMode) { - case IdXSend: - xv->TextFlag = 0; - - // t@CMJnOÉA"rx t@C¼"ð©®IÉÄÑo·B(2007.12.20 yutaka) - if (ts->XModemRcvCommand[0] != '\0') { - _snprintf_s(inistr, sizeof(inistr), _TRUNCATE, "%s %s\015", - ts->XModemRcvCommand, &(fv->FullName[fv->DirLen])); - FTConvFName(inistr + strlen(ts->XModemRcvCommand) + 1); - XWrite(fv, xv, cv, inistr, strlen(inistr)); - } - - FTSetTimeOut(fv, TimeOutVeryLong); - break; - case IdXReceive: - XSendNAK(fv, xv, cv); - break; - } -} - -void XCancel(PFileVar fv, PXVar xv, PComVar cv) -{ - BYTE b; - - b = CAN; - XWrite(fv, xv, cv, &b, 1); - xv->XMode = 0; // quit -} - -void XTimeOutProc(PFileVar fv, PXVar xv, PComVar cv) -{ - switch (xv->XMode) { - case IdXSend: - xv->XMode = 0; // quit - break; - case IdXReceive: - XSendNAK(fv, xv, cv); - break; - } -} - -BOOL XReadPacket(PFileVar fv, PXVar xv, PComVar cv) -{ - BYTE b, d; - int i, c; - BOOL GetPkt; - - c = XRead1Byte(fv, xv, cv, &b); - - GetPkt = FALSE; - - while ((c > 0) && (!GetPkt)) { - switch (xv->PktReadMode) { - case XpktSOH: - if (b == SOH) { - xv->PktIn[0] = b; - xv->PktReadMode = XpktBLK; - if (xv->XOpt == Xopt1K) - XSetOpt(fv, xv, XoptCRC); - FTSetTimeOut(fv, xv->TOutShort); - } else if (b == STX) { - xv->PktIn[0] = b; - xv->PktReadMode = XpktBLK; - XSetOpt(fv, xv, Xopt1K); - FTSetTimeOut(fv, xv->TOutShort); - } else if (b == EOT) { - b = ACK; - fv->Success = TRUE; - XWrite(fv, xv, cv, &b, 1); - return FALSE; - } else { - /* flush comm buffer */ - cv->InBuffCount = 0; - cv->InPtr = 0; - return TRUE; - } - break; - case XpktBLK: - xv->PktIn[1] = b; - xv->PktReadMode = XpktBLK2; - FTSetTimeOut(fv, xv->TOutShort); - break; - case XpktBLK2: - xv->PktIn[2] = b; - if ((b ^ xv->PktIn[1]) == 0xff) { - xv->PktBufPtr = 3; - xv->PktBufCount = xv->DataLen + xv->CheckLen; - xv->PktReadMode = XpktDATA; - FTSetTimeOut(fv, xv->TOutShort); - } else - XSendNAK(fv, xv, cv); - break; - case XpktDATA: - xv->PktIn[xv->PktBufPtr] = b; - xv->PktBufPtr++; - xv->PktBufCount--; - GetPkt = xv->PktBufCount == 0; - if (GetPkt) { - FTSetTimeOut(fv, xv->TOutLong); - xv->PktReadMode = XpktSOH; - } else - FTSetTimeOut(fv, xv->TOutShort); - break; - } - - if (!GetPkt) - c = XRead1Byte(fv, xv, cv, &b); - } - - if (!GetPkt) - return TRUE; - - if ((xv->PktIn[1] == 0) && (xv->PktNum == 0) && - (xv->PktNumOffset == 0)) { - if (xv->NAKMode == XnakNAK) - xv->NAKCount = 10; - else - xv->NAKCount = 3; - XSendNAK(fv, xv, cv); - return TRUE; - } - - GetPkt = XCheckPacket(xv); - if (!GetPkt) { - XSendNAK(fv, xv, cv); - return TRUE; - } - - d = xv->PktIn[1] - xv->PktNum; - if (d > 1) { - XCancel(fv, xv, cv); - return FALSE; - } - - /* send ACK */ - b = ACK; - XWrite(fv, xv, cv, &b, 1); - xv->NAKMode = XnakNAK; - xv->NAKCount = 10; - - if (d == 0) - return TRUE; - xv->PktNum = xv->PktIn[1]; - if (xv->PktNum == 0) - xv->PktNumOffset = xv->PktNumOffset + 256; - - c = xv->DataLen; - if (xv->TextFlag > 0) - while ((c > 0) && (xv->PktIn[2 + c] == 0x1A)) - c--; - - if (xv->TextFlag > 0) - for (i = 0; i <= c - 1; i++) { - b = xv->PktIn[3 + i]; - if ((b == LF) && (!xv->CRRecv)) - _lwrite(fv->FileHandle, "\015", 1); - if (xv->CRRecv && (b != LF)) - _lwrite(fv->FileHandle, "\012", 1); - xv->CRRecv = b == CR; - _lwrite(fv->FileHandle, &b, 1); - } else - _lwrite(fv->FileHandle, &(xv->PktIn[3]), c); - - fv->ByteCount = fv->ByteCount + c; - - SetDlgNum(fv->HWin, IDC_PROTOPKTNUM, xv->PktNumOffset + xv->PktNum); - SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount); - - FTSetTimeOut(fv, xv->TOutLong); - - return TRUE; -} - -BOOL XSendPacket(PFileVar fv, PXVar xv, PComVar cv) -{ - BYTE b; - int i; - BOOL SendFlag; - WORD Check; - - SendFlag = FALSE; - if (xv->PktBufCount == 0) { - i = XRead1Byte(fv, xv, cv, &b); - do { - if (i == 0) - return TRUE; - switch (b) { - case ACK: - if (!fv->FileOpen) { - fv->Success = TRUE; - return FALSE; - } else if (xv->PktNumSent == (BYTE) (xv->PktNum + 1)) { - xv->PktNum = xv->PktNumSent; - if (xv->PktNum == 0) - xv->PktNumOffset = xv->PktNumOffset + 256; - SendFlag = TRUE; - } - break; - case NAK: - if (xv->PktNum == 0 && xv->XOpt == Xopt1K) { - /* we wanted 1k with CRC, but the other end specified checksum */ - /* keep the 1k block, but move back to checksum mode. */ - xv->XOpt = XoptCheck; - xv->CheckLen = 1; - } - SendFlag = TRUE; - break; - case CAN: - break; - case 0x43: - if ((xv->PktNum == 0) && (xv->PktNumOffset == 0)) { - if ((xv->XOpt == XoptCheck) && (xv->PktNumSent == 0)) - XSetOpt(fv, xv, XoptCRC); - if (xv->XOpt != XoptCheck) - SendFlag = TRUE; - } - break; - } - if (!SendFlag) - i = XRead1Byte(fv, xv, cv, &b); - } while (!SendFlag); - // reset timeout timer - FTSetTimeOut(fv, TimeOutVeryLong); - - do { - i = XRead1Byte(fv, xv, cv, &b); - } while (i != 0); - - if (xv->PktNumSent == xv->PktNum) { /* make a new packet */ - xv->PktNumSent++; - if (xv->DataLen == 128) - xv->PktOut[0] = SOH; - else - xv->PktOut[0] = STX; - xv->PktOut[1] = xv->PktNumSent; - xv->PktOut[2] = ~xv->PktNumSent; - - i = 1; - while ((i <= xv->DataLen) && fv->FileOpen && - (_lread(fv->FileHandle, &b, 1) == 1)) { - xv->PktOut[2 + i] = b; - i++; - fv->ByteCount++; - } - - if (i > 1) { - while (i <= xv->DataLen) { - xv->PktOut[2 + i] = 0x1A; - i++; - } - - Check = XCalcCheck(xv, xv->PktOut); - if (xv->CheckLen == 1) /* Checksum */ - xv->PktOut[xv->DataLen + 3] = (BYTE) Check; - else { - xv->PktOut[xv->DataLen + 3] = HIBYTE(Check); - xv->PktOut[xv->DataLen + 4] = LOBYTE(Check); - } - xv->PktBufCount = 3 + xv->DataLen + xv->CheckLen; - } else { /* send EOT */ - if (fv->FileOpen) { - _lclose(fv->FileHandle); - fv->FileHandle = 0; - fv->FileOpen = FALSE; - } - xv->PktOut[0] = EOT; - xv->PktBufCount = 1; - } - } else { /* resend packet */ - xv->PktBufCount = 3 + xv->DataLen + xv->CheckLen; - } - xv->PktBufPtr = 0; - } - /* a NAK or C could have arrived while we were buffering. Consume it. */ - do { - i = XRead1Byte(fv, xv, cv, &b); - } while (i != 0); - - i = 1; - while ((xv->PktBufCount > 0) && (i > 0)) { - b = xv->PktOut[xv->PktBufPtr]; - i = XWrite(fv, xv, cv, &b, 1); - if (i > 0) { - xv->PktBufCount--; - xv->PktBufPtr++; - } - } - - if (xv->PktBufCount == 0) { - SetDlgNum(fv->HWin, IDC_PROTOPKTNUM, - xv->PktNumOffset + xv->PktNumSent); - SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount); - SetDlgPercent(fv->HWin, IDC_PROTOPERCENT, IDC_PROTOPROGRESS, - fv->ByteCount, fv->FileSize, &fv->ProgStat); - } - - return TRUE; -} +/* Tera Term + Copyright(C) 1994-1998 T. Teranishi + All rights reserved. */ + +/* TTFILE.DLL, XMODEM protocol */ +#include "teraterm.h" +#include "tttypes.h" +#include "ttftypes.h" +#include <stdio.h> + +#include "tt_res.h" +#include "ttcommon.h" +#include "ttlib.h" +#include "ftlib.h" +#include "dlglib.h" + +#include "xmodem.h" + +#define TimeOutInit 10 +#define TimeOutC 3 +#define TimeOutShort 10 +#define TimeOutLong 20 +#define TimeOutVeryLong 60 + +int XRead1Byte(PFileVar fv, PXVar xv, PComVar cv, LPBYTE b) +{ + if (CommRead1Byte(cv, b) == 0) + return 0; + + if (fv->LogFlag) { + if (fv->LogState == 0) { + // cèÌASCII\¦ðs¤ + fv->FlushLogLineBuf = 1; + FTLog1Byte(fv, 0); + fv->FlushLogLineBuf = 0; + + fv->LogState = 1; + fv->LogCount = 0; + _lwrite(fv->LogFile, "\015\012<<<\015\012", 7); + } + FTLog1Byte(fv, *b); + } + return 1; +} + +int XWrite(PFileVar fv, PXVar xv, PComVar cv, PCHAR B, int C) +{ + int i, j; + + i = CommBinaryOut(cv, B, C); + if (fv->LogFlag && (i > 0)) { + if (fv->LogState != 0) { + // cèÌASCII\¦ðs¤ + fv->FlushLogLineBuf = 1; + FTLog1Byte(fv, 0); + fv->FlushLogLineBuf = 0; + + fv->LogState = 0; + fv->LogCount = 0; + _lwrite(fv->LogFile, "\015\012>>>\015\012", 7); + } + for (j = 0; j <= i - 1; j++) + FTLog1Byte(fv, B[j]); + } + return i; +} + +void XSetOpt(PFileVar fv, PXVar xv, WORD Opt) +{ + char Tmp[21]; + + xv->XOpt = Opt; + + strncpy_s(Tmp, sizeof(Tmp), "XMODEM (", _TRUNCATE); + switch (xv->XOpt) { + case XoptCheck: /* Checksum */ + strncat_s(Tmp, sizeof(Tmp), "checksum)", _TRUNCATE); + xv->DataLen = 128; + xv->CheckLen = 1; + break; + case XoptCRC: /* CRC */ + strncat_s(Tmp, sizeof(Tmp), "CRC)", _TRUNCATE); + xv->DataLen = 128; + xv->CheckLen = 2; + break; + case Xopt1K: /* 1K */ + strncat_s(Tmp, sizeof(Tmp), "1K)", _TRUNCATE); + xv->DataLen = 1024; + xv->CheckLen = 2; + break; + } + SetDlgItemText(fv->HWin, IDC_PROTOPROT, Tmp); +} + +void XSendNAK(PFileVar fv, PXVar xv, PComVar cv) +{ + BYTE b; + int t; + + /* flush comm buffer */ + cv->InBuffCount = 0; + cv->InPtr = 0; + + xv->NAKCount--; + if (xv->NAKCount < 0) { + if (xv->NAKMode == XnakC) { + XSetOpt(fv, xv, XoptCheck); + xv->NAKMode = XnakNAK; + xv->NAKCount = 9; + } else { + XCancel(fv, xv, cv); + return; + } + } + + if (xv->NAKMode == XnakNAK) { + b = NAK; + if ((xv->PktNum == 0) && (xv->PktNumOffset == 0)) + t = TimeOutInit; + else + t = xv->TOutLong; + } else { + b = 'C'; + t = TimeOutC; + } + XWrite(fv, xv, cv, &b, 1); + xv->PktReadMode = XpktSOH; + FTSetTimeOut(fv, t); +} + +WORD XCalcCheck(PXVar xv, PCHAR PktBuf) +{ + int i; + WORD Check; + + if (xv->CheckLen == 1) { /* CheckSum */ + /* Calc sum */ + Check = 0; + for (i = 0; i <= xv->DataLen - 1; i++) + Check = Check + (BYTE) (PktBuf[3 + i]); + return (Check & 0xff); + } else { /* CRC */ + Check = 0; + for (i = 0; i <= xv->DataLen - 1; i++) + Check = UpdateCRC(PktBuf[3 + i], Check); + return (Check); + } +} + +BOOL XCheckPacket(PXVar xv) +{ + WORD Check; + + Check = XCalcCheck(xv, xv->PktIn); + if (xv->CheckLen == 1) /* Checksum */ + return ((BYTE) Check == xv->PktIn[xv->DataLen + 3]); + else + return ((HIBYTE(Check) == xv->PktIn[xv->DataLen + 3]) && + (LOBYTE(Check) == xv->PktIn[xv->DataLen + 4])); +} + +void XInit(PFileVar fv, PXVar xv, PComVar cv, PTTSet ts) { + char inistr[MAXPATHLEN + 10]; + + fv->LogFlag = ((ts->LogFlag & LOG_X) != 0); + if (fv->LogFlag) + fv->LogFile = _lcreat("XMODEM.LOG", 0); + fv->LogState = 0; + fv->LogCount = 0; + + fv->FileSize = 0; + if ((xv->XMode == IdXSend) && fv->FileOpen) { + fv->FileSize = GetFSize(fv->FullName); + InitDlgProgress(fv->HWin, IDC_PROTOPROGRESS, &fv->ProgStat); + } else { + fv->ProgStat = -1; + } + + SetWindowText(fv->HWin, fv->DlgCaption); + SetDlgItemText(fv->HWin, IDC_PROTOFNAME, &(fv->FullName[fv->DirLen])); + + xv->PktNumOffset = 0; + xv->PktNum = 0; + xv->PktNumSent = 0; + xv->PktBufCount = 0; + xv->CRRecv = FALSE; + + fv->ByteCount = 0; + + if (cv->PortType == IdTCPIP) { + xv->TOutShort = TimeOutVeryLong; + xv->TOutLong = TimeOutVeryLong; + } else { + xv->TOutShort = TimeOutShort; + xv->TOutLong = TimeOutLong; + } + + XSetOpt(fv, xv, xv->XOpt); + + if (xv->XOpt == XoptCheck) { + xv->NAKMode = XnakNAK; + xv->NAKCount = 10; + } else { + xv->NAKMode = XnakC; + xv->NAKCount = 3; + } + + switch (xv->XMode) { + case IdXSend: + xv->TextFlag = 0; + + // t@CMJnOÉA"rx t@C¼"ð©®IÉÄÑo·B(2007.12.20 yutaka) + if (ts->XModemRcvCommand[0] != '\0') { + _snprintf_s(inistr, sizeof(inistr), _TRUNCATE, "%s %s\015", + ts->XModemRcvCommand, &(fv->FullName[fv->DirLen])); + FTConvFName(inistr + strlen(ts->XModemRcvCommand) + 1); + XWrite(fv, xv, cv, inistr, strlen(inistr)); + } + + FTSetTimeOut(fv, TimeOutVeryLong); + break; + case IdXReceive: + XSendNAK(fv, xv, cv); + break; + } +} + +void XCancel(PFileVar fv, PXVar xv, PComVar cv) +{ + // five cancels & five backspaces per spec + BYTE cancel[] = { CAN, CAN, CAN, CAN, CAN, BS, BS, BS, BS, BS }; + + XWrite(fv,xv,cv, (PCHAR)&cancel, sizeof(cancel)); + xv->XMode = 0; // quit +} + +void XTimeOutProc(PFileVar fv, PXVar xv, PComVar cv) +{ + switch (xv->XMode) { + case IdXSend: + xv->XMode = 0; // quit + break; + case IdXReceive: + XSendNAK(fv, xv, cv); + break; + } +} + +BOOL XReadPacket(PFileVar fv, PXVar xv, PComVar cv) +{ + BYTE b, d; + int i, c; + BOOL GetPkt; + + c = XRead1Byte(fv, xv, cv, &b); + + GetPkt = FALSE; + + while ((c > 0) && (!GetPkt)) { + switch (xv->PktReadMode) { + case XpktSOH: + if (b == SOH) { + xv->PktIn[0] = b; + xv->PktReadMode = XpktBLK; + if (xv->XOpt == Xopt1K) + XSetOpt(fv, xv, XoptCRC); + FTSetTimeOut(fv, xv->TOutShort); + } else if (b == STX) { + xv->PktIn[0] = b; + xv->PktReadMode = XpktBLK; + XSetOpt(fv, xv, Xopt1K); + FTSetTimeOut(fv, xv->TOutShort); + } else if (b == EOT) { + b = ACK; + fv->Success = TRUE; + XWrite(fv, xv, cv, &b, 1); + return FALSE; + } else { + /* flush comm buffer */ + cv->InBuffCount = 0; + cv->InPtr = 0; + return TRUE; + } + break; + case XpktBLK: + xv->PktIn[1] = b; + xv->PktReadMode = XpktBLK2; + FTSetTimeOut(fv, xv->TOutShort); + break; + case XpktBLK2: + xv->PktIn[2] = b; + if ((b ^ xv->PktIn[1]) == 0xff) { + xv->PktBufPtr = 3; + xv->PktBufCount = xv->DataLen + xv->CheckLen; + xv->PktReadMode = XpktDATA; + FTSetTimeOut(fv, xv->TOutShort); + } else + XSendNAK(fv, xv, cv); + break; + case XpktDATA: + xv->PktIn[xv->PktBufPtr] = b; + xv->PktBufPtr++; + xv->PktBufCount--; + GetPkt = xv->PktBufCount == 0; + if (GetPkt) { + FTSetTimeOut(fv, xv->TOutLong); + xv->PktReadMode = XpktSOH; + } else + FTSetTimeOut(fv, xv->TOutShort); + break; + } + + if (!GetPkt) + c = XRead1Byte(fv, xv, cv, &b); + } + + if (!GetPkt) + return TRUE; + + if ((xv->PktIn[1] == 0) && (xv->PktNum == 0) && + (xv->PktNumOffset == 0)) { + if (xv->NAKMode == XnakNAK) + xv->NAKCount = 10; + else + xv->NAKCount = 3; + XSendNAK(fv, xv, cv); + return TRUE; + } + + GetPkt = XCheckPacket(xv); + if (!GetPkt) { + XSendNAK(fv, xv, cv); + return TRUE; + } + + d = xv->PktIn[1] - xv->PktNum; + if (d > 1) { + XCancel(fv, xv, cv); + return FALSE; + } + + /* send ACK */ + b = ACK; + XWrite(fv, xv, cv, &b, 1); + xv->NAKMode = XnakNAK; + xv->NAKCount = 10; + + if (d == 0) + return TRUE; + xv->PktNum = xv->PktIn[1]; + if (xv->PktNum == 0) + xv->PktNumOffset = xv->PktNumOffset + 256; + + c = xv->DataLen; + if (xv->TextFlag > 0) + while ((c > 0) && (xv->PktIn[2 + c] == 0x1A)) + c--; + + if (xv->TextFlag > 0) + for (i = 0; i <= c - 1; i++) { + b = xv->PktIn[3 + i]; + if ((b == LF) && (!xv->CRRecv)) + _lwrite(fv->FileHandle, "\015", 1); + if (xv->CRRecv && (b != LF)) + _lwrite(fv->FileHandle, "\012", 1); + xv->CRRecv = b == CR; + _lwrite(fv->FileHandle, &b, 1); + } else + _lwrite(fv->FileHandle, &(xv->PktIn[3]), c); + + fv->ByteCount = fv->ByteCount + c; + + SetDlgNum(fv->HWin, IDC_PROTOPKTNUM, xv->PktNumOffset + xv->PktNum); + SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount); + + FTSetTimeOut(fv, xv->TOutLong); + + return TRUE; +} + +BOOL XSendPacket(PFileVar fv, PXVar xv, PComVar cv) +{ + BYTE b; + int i; + BOOL SendFlag; + WORD Check; + + SendFlag = FALSE; + if (xv->PktBufCount == 0) { + i = XRead1Byte(fv, xv, cv, &b); + do { + if (i == 0) + return TRUE; + switch (b) { + case ACK: + if (!fv->FileOpen) { + fv->Success = TRUE; + return FALSE; + } else if (xv->PktNumSent == (BYTE) (xv->PktNum + 1)) { + xv->PktNum = xv->PktNumSent; + if (xv->PktNum == 0) + xv->PktNumOffset = xv->PktNumOffset + 256; + SendFlag = TRUE; + } + break; + case NAK: + if (xv->PktNum == 0 && xv->XOpt == Xopt1K) { + /* we wanted 1k with CRC, but the other end specified checksum */ + /* keep the 1k block, but move back to checksum mode. */ + xv->XOpt = XoptCheck; + xv->CheckLen = 1; + } + SendFlag = TRUE; + break; + case CAN: + break; + case 0x43: + if ((xv->PktNum == 0) && (xv->PktNumOffset == 0)) { + if ((xv->XOpt == XoptCheck) && (xv->PktNumSent == 0)) + XSetOpt(fv, xv, XoptCRC); + if (xv->XOpt != XoptCheck) + SendFlag = TRUE; + } + break; + } + if (!SendFlag) + i = XRead1Byte(fv, xv, cv, &b); + } while (!SendFlag); + // reset timeout timer + FTSetTimeOut(fv, TimeOutVeryLong); + + do { + i = XRead1Byte(fv, xv, cv, &b); + } while (i != 0); + + if (xv->PktNumSent == xv->PktNum) { /* make a new packet */ + xv->PktNumSent++; + if (xv->DataLen == 128) + xv->PktOut[0] = SOH; + else + xv->PktOut[0] = STX; + xv->PktOut[1] = xv->PktNumSent; + xv->PktOut[2] = ~xv->PktNumSent; + + i = 1; + while ((i <= xv->DataLen) && fv->FileOpen && + (_lread(fv->FileHandle, &b, 1) == 1)) { + xv->PktOut[2 + i] = b; + i++; + fv->ByteCount++; + } + + if (i > 1) { + while (i <= xv->DataLen) { + xv->PktOut[2 + i] = 0x1A; + i++; + } + + Check = XCalcCheck(xv, xv->PktOut); + if (xv->CheckLen == 1) /* Checksum */ + xv->PktOut[xv->DataLen + 3] = (BYTE) Check; + else { + xv->PktOut[xv->DataLen + 3] = HIBYTE(Check); + xv->PktOut[xv->DataLen + 4] = LOBYTE(Check); + } + xv->PktBufCount = 3 + xv->DataLen + xv->CheckLen; + } else { /* send EOT */ + if (fv->FileOpen) { + _lclose(fv->FileHandle); + fv->FileHandle = 0; + fv->FileOpen = FALSE; + } + xv->PktOut[0] = EOT; + xv->PktBufCount = 1; + } + } else { /* resend packet */ + xv->PktBufCount = 3 + xv->DataLen + xv->CheckLen; + } + xv->PktBufPtr = 0; + } + /* a NAK or C could have arrived while we were buffering. Consume it. */ + do { + i = XRead1Byte(fv, xv, cv, &b); + } while (i != 0); + + i = 1; + while ((xv->PktBufCount > 0) && (i > 0)) { + b = xv->PktOut[xv->PktBufPtr]; + i = XWrite(fv, xv, cv, &b, 1); + if (i > 0) { + xv->PktBufCount--; + xv->PktBufPtr++; + } + } + + if (xv->PktBufCount == 0) { + SetDlgNum(fv->HWin, IDC_PROTOPKTNUM, + xv->PktNumOffset + xv->PktNumSent); + SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount); + SetDlgPercent(fv->HWin, IDC_PROTOPERCENT, IDC_PROTOPROGRESS, + fv->ByteCount, fv->FileSize, &fv->ProgStat); + } + + return TRUE; +} Modified: trunk/teraterm/ttpfile/ymodem.c =================================================================== --- trunk/teraterm/ttpfile/ymodem.c 2010-04-12 12:51:24 UTC (rev 3854) +++ trunk/teraterm/ttpfile/ymodem.c 2010-04-12 13:43:07 UTC (rev 3855) @@ -1,794 +1,796 @@ -/* Tera Term -Copyright(C) 2008-2010 TeraTerm Project -All rights reserved. */ - -/* TTFILE.DLL, YMODEM protocol */ -#include "teraterm.h" -#include "tttypes.h" -#include "ttftypes.h" -#include <stdio.h> -#include <time.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "tt_res.h" -#include "ttcommon.h" -#include "ttlib.h" -#include "ftlib.h" -#include "dlglib.h" - -#include "ymodem.h" - -#define TimeOutInit 10 -#define TimeOutC 3 -#define TimeOutShort 10 -#define TimeOutLong 20 -#define TimeOutVeryLong 60 - -// f[^]TCYBYMODEMÅÍ 128 or 1024 byte ðT|[g·éB -#define SOH_DATALEN 128 -#define STX_DATALEN 1024 - -int YRead1Byte(PFileVar fv, PYVar yv, PComVar cv, LPBYTE b) -{ - if (CommRead1Byte(cv,b) == 0) - return 0; - - if (fv->LogFlag) - { - if (fv->LogState==0) - { - // cèÌASCII\¦ðs¤ - fv->FlushLogLineBuf = 1; - FTLog1Byte(fv,0); - fv->FlushLogLineBuf = 0; - - fv->LogState = 1; - fv->LogCount = 0; - fv->FlushLogLineBuf = 0; - _lwrite(fv->LogFile,"\015\012<<<\015\012",7); - } - FTLog1Byte(fv,*b); - } - return 1; -} - -int YWrite(PFileVar fv, PYVar yv, PComVar cv, PCHAR B, int C) -{ - int i, j; - - i = CommBinaryOut(cv,B,C); - if (fv->LogFlag && (i>0)) - { - if (fv->LogState != 0) - { - // cèÌASCII\¦ðs¤ - fv->FlushLogLineBuf = 1; - FTLog1Byte(fv,0); - fv->FlushLogLineBuf = 0; - - fv->LogState = 0; - fv->LogCount = 0; - _lwrite(fv->LogFile,"\015\012>>>\015\012",7); - } - for (j=0 ; j <= i-1 ; j++) - FTLog1Byte(fv,B[j]); - } - return i; -} - -void YSetOpt(PFileVar fv, PYVar yv, WORD Opt) -{ - char Tmp[21]; - - yv->YOpt = Opt; - - strncpy_s(Tmp, sizeof(Tmp),"YMODEM (", _TRUNCATE); - switch (yv->YOpt) { - case Yopt1K: /* YMODEM */ - strncat_s(Tmp,sizeof(Tmp),"1k)",_TRUNCATE); - yv->DataLen = 1024; - yv->CheckLen = 2; - break; - case YoptG: /* YMODEM-g */ - strncat_s(Tmp,sizeof(Tmp),"-g)",_TRUNCATE); - yv->DataLen = 1024; - yv->CheckLen = 2; - break; - case YoptSingle: /* YMODEM(-g) single mode */ - strncat_s(Tmp,sizeof(Tmp),"single mode)",_TRUNCATE); - yv->DataLen = 1024; - yv->CheckLen = 2; - break; - } - SetDlgItemText(fv->HWin, IDC_PROTOPROT, Tmp); -} - -void YSendNAK(PFileVar fv, PYVar yv, PComVar cv) -{ - BYTE b; - int t; - - /* flush comm buffer */ - cv->InBuffCount = 0; - cv->InPtr = 0; - - yv->NAKCount--; - if (yv->NAKCount<0) - { - if (yv->NAKMode==YnakC) - { - YSetOpt(fv,yv,XoptCheck); - yv->NAKMode = YnakC; - yv->NAKCount = 9; - } - else { - YCancel(fv,yv,cv); - return; - } - } - - if (yv->NAKMode!=YnakC) - { - b = NAK; - if ((yv->PktNum==0) && (yv->PktNumOffset==0)) - t = TimeOutInit; - else - t = yv->TOutLong; - } - else { - b = 'C'; - t = TimeOutC; - } - YWrite(fv,yv,cv,&b,1); - yv->PktReadMode = XpktSOH; - FTSetTimeOut(fv,t); -} - -WORD YCalcCheck(PYVar yv, PCHAR PktBuf) -{ - int i; - WORD Check; - - if (yv->CheckLen==1) /* CheckSum */ - { - /* Calc sum */ - Check = 0; - for (i = 0 ; i <= yv->DataLen-1 ; i++) - Check = Check + (BYTE)(PktBuf[3+i]); - return (Check & 0xff); - } - else { /* CRC */ - Check = 0; - for (i = 0 ; i <= yv->DataLen-1 ; i++) - Check = UpdateCRC(PktBuf[3+i],Check); - return (Check); - } -} - -BOOL YCheckPacket(PYVar yv) -{ - WORD Check; - - Check = YCalcCheck(yv,yv->PktIn); - if (yv->CheckLen==1) /* Checksum */ - return ((BYTE)Check==yv->PktIn[yv->DataLen+3]); - else - return ((HIBYTE(Check)==yv->PktIn[yv->DataLen+3]) && - (LOBYTE(Check)==yv->PktIn[yv->DataLen+4])); -} - -static void initialize_file_info(PFileVar fv, PYVar yv) -{ - if (yv->YMode == IdYSend) { - if (fv->FileOpen) { - _lclose(fv->FileHandle); - } - fv->FileHandle = _lopen(fv->FullName,OF_READ); - fv->FileSize = GetFSize(fv->FullName); - } else { - fv->FileHandle = -1; - fv->FileSize = 0; - } - fv->FileOpen = fv->FileHandle>0; - - if (yv->YMode == IdYSend) { - InitDlgProgress(fv->HWin, IDC_PROTOPROGRESS, &fv->ProgStat); - } else { - fv->ProgStat = -1; - } - SetDlgItemText(fv->HWin, IDC_PROTOFNAME, &(fv->FullName[fv->DirLen])); - - yv->PktNumOffset = 0; - yv->PktNum = 0; - yv->PktNumSent = 0; - yv->PktBufCount = 0; - yv->CRRecv = FALSE; - fv->ByteCount = 0; - yv->SendFileInfo = 0; - yv->SendEot = 0; - yv->LastSendEot = 0; -} - -void YInit -(PFileVar fv, PYVar yv, PComVar cv, PTTSet ts) -{ - char inistr[MAXPATHLEN + 10]; - - if (yv->YMode == IdYSend) { - if (!GetNextFname(fv)) { - return; - } - } - - fv->LogFlag = ((ts->LogFlag & LOG_Y)!=0); - if (fv->LogFlag) - fv->LogFile = _lcreat("YMODEM.LOG",0); - fv->LogState = 0; - fv->LogCount = 0; - - SetWindowText(fv->HWin, fv->DlgCaption); - - initialize_file_info(fv, yv); - - if (cv->PortType==IdTCPIP) - { - yv->TOutShort = TimeOutVeryLong; - yv->TOutLong = TimeOutVeryLong; - } - else { - yv->TOutShort = TimeOutShort; - yv->TOutLong = TimeOutLong; - } - - YSetOpt(fv,yv,yv->YOpt); - - if (yv->YOpt == Yopt1K) - { - yv->NAKMode = YnakC; - yv->NAKCount = 10; - } - else { - yv->NAKMode = YnakG; - yv->NAKCount = 10; - } - - if (fv->LogFlag) { - char buf[128]; - time_t tm = time(NULL); - - _snprintf_s(buf, sizeof(buf), _TRUNCATE, "YMODEM %s start: %s\n", - yv->YMode == IdYSend ? "Send" : "Recv", - ctime(&tm) - ); - _lwrite(fv->LogFile, buf, strlen(buf)); - } - - switch (yv->YMode) { - case IdYSend: - yv->TextFlag = 0; - - // t@CMJnOÉA"rb t@C¼"ð©®IÉÄÑo·B(2007.12.20 yutaka) - //strcpy(ts->YModemRcvCommand, "rb"); - if (ts->YModemRcvCommand[0] != '\0') { - _snprintf_s(inistr, sizeof(inistr), _TRUNCATE, "%s\015", - ts->YModemRcvCommand); - YWrite(fv,yv,cv, inistr , strlen(inistr)); - } - - FTSetTimeOut(fv,TimeOutVeryLong); - break; - - case IdYReceive: -#if 0 // for debug - strcpy(inistr, "sb -b svnrev.exe lrzsz-0.12.20.tar.gz\r\n"); -// strcpy(inistr, "sb url3.txt url4.txt url5.txt\r\n"); - YWrite(fv,yv,cv, inistr , strlen(inistr)); -#endif - yv->TextFlag = 0; - - YSendNAK(fv,yv,cv); - - break; - } -} - -void YCancel(PFileVar fv, PYVar yv, PComVar cv) -{ - BYTE b; - - b = CAN; - YWrite(fv,yv,cv,&b,1); - yv->YMode = 0; // quit -} - -void YTimeOutProc(PFileVar fv, PYVar yv, PComVar cv) -{ - switch (yv->YMode) { - case IdXSend: - yv->YMode = 0; // quit - break; - case IdXReceive: - YSendNAK(fv,yv,cv); - break; - } -} - -// YMODEMT[o©çt@CðóM·éÛAProtoParse()©çÄÑo³êéÖB -// -// +-------+-------+--------+---------+-----+ -// |Header |Block# |1-Block#| Payload | CRC | -// +-------+-------+--------+---------+-----+ -// 1 1 1 128/1024 2 byte -// -// return TRUE: t@CóM -// FALSE: óM®¹ -BOOL YReadPacket(PFileVar fv, PYVar yv, PComVar cv) -{ - BYTE b, d; - int i, c, nak; - BOOL GetPkt; - - c = YRead1Byte(fv,yv,cv,&b); - - GetPkt = FALSE; - - while ((c>0) && (! GetPkt)) - { - switch (yv->PktReadMode) { - case XpktSOH: - // SOH © STX ©ÅubN·ªÜéB - if (b==SOH) - { - yv->PktIn[0] = b; - yv->PktReadMode = XpktBLK; - yv->DataLen = SOH_DATALEN; - FTSetTimeOut(fv,yv->TOutShort); - } - else if (b==STX) - { - yv->PktIn[0] = b; - yv->PktReadMode = XpktBLK; - yv->DataLen = STX_DATALEN; - FTSetTimeOut(fv,yv->TOutShort); - } - else if (b==EOT) - { - // EOTª½çA1ÂÌt@CóMª®¹µ½±Æð¦·B - if (fv->FileOpen) { - fv->FileOpen = 0; - _lclose(fv->FileHandle); - fv->FileHandle = -1; - } - - initialize_file_info(fv, yv); - - // EOTÉεÄACKðÔ· - b = ACK; - YWrite(fv,yv,cv,&b, 1); - - // Ìt@CM𣷽ßA'C'ðéB - YSendNAK(fv,yv,cv); - - return TRUE; - } - else { - /* flush comm buffer */ - cv->InBuffCount = 0; - cv->InPtr = 0; - return TRUE; - } - break; - case XpktBLK: - yv->PktIn[1] = b; - yv->PktReadMode = XpktBLK2; - FTSetTimeOut(fv,yv->TOutShort); - break; - case XpktBLK2: - nak = 1; - yv->PktIn[2] = b; - if ((b ^ yv->PktIn[1]) == 0xff) { - nak = 0; - if (yv->SendFileInfo) { - if (yv->PktIn[1] == (BYTE)(yv->PktNum + 1)) // ÌubNÔ© - nak = 0; - } - } - - if (nak == 0) - { - yv->PktBufPtr = 3; - yv->PktBufCount = yv->DataLen + yv->CheckLen; - yv->PktReadMode = XpktDATA; - FTSetTimeOut(fv,yv->TOutShort); - } - else - YSendNAK(fv,yv,cv); - break; - case XpktDATA: - yv->PktIn[yv->PktBufPtr] = b; - yv->PktBufPtr++; - yv->PktBufCount--; - GetPkt = yv->PktBufCount==0; - if (GetPkt) - { - FTSetTimeOut(fv,yv->TOutLong); - yv->PktReadMode = XpktSOH; - } - else - FTSetTimeOut(fv,yv->TOutShort); - break; - } - - if (! GetPkt) c = YRead1Byte(fv,yv,cv,&b); - } - - if (! GetPkt) return TRUE; - - GetPkt = YCheckPacket(yv); - if (! GetPkt) - { - YSendNAK(fv,yv,cv); - return TRUE; - } - - // I[[ÈçÎASt@CóMÌ®¹ð¦·B - if (yv->PktIn[1] == 0x00 && yv->PktIn[2] == 0xFF && - yv->SendFileInfo == 0 - ) { - c = yv->DataLen; - while ((c>0) && (yv->PktIn[2+c]==0x00)) - c--; - if (c == 0) { - b = ACK; - YWrite(fv,yv,cv,&b, 1); - fv->Success = TRUE; - return FALSE; - } - } - - d = yv->PktIn[1] - yv->PktNum; - if (d>1) - { - YCancel(fv,yv,cv); - return FALSE; - } - - /* send ACK */ - b = ACK; - YWrite(fv,yv,cv,&b, 1); - yv->NAKMode = YnakC; - yv->NAKCount = 10; - - // d¡µÄ¢éêÍA½àµÈ¢B - if (yv->SendFileInfo && - yv->PktIn[1] == (BYTE)(yv->PktNum)) { - return TRUE; - } - - yv->PktNum = yv->PktIn[1]; - - // YMODEMÌêAblock#0ªut@CîñvÆÈéB - if (d == 0 && - yv->SendFileInfo == 0) { - long modtime; - long bytes_total; - int mode; - int ret; - BYTE *p; - char *name, *nameend; - - p = &(yv->PktIn[3]); - name = p; - strncpy_s(fv->FullName, sizeof(fv->FullName), name, _TRUNCATE); - nameend = name + 1 + strlen(name); - if (*nameend) { - ret = sscanf(nameend, "%ld%lo%o", &bytes_total, &modtime, &mode); - if (ret == 3) { - fv->FileSize = bytes_total; - } - } - fv->FileHandle = _lcreat(fv->FullName,0); - fv->FileOpen = fv->FileHandle>0; - - fv->DirLen = 0; - SetDlgItemText(fv->HWin, IDC_PROTOFNAME, &(fv->FullName[fv->DirLen])); - - yv->SendFileInfo = 1; - - return TRUE; - } - - if (yv->PktNum==0) - yv->PktNumOffset = yv->PktNumOffset + 256; - - c = yv->DataLen; - if (yv->TextFlag>0) - while ((c>0) && (yv->PktIn[2+c]==0x1A)) - c--; - - // ÅIubNÌ]ªÈf[^ð·é - if (fv->ByteCount + c > fv->FileSize) { - c = fv->FileSize - fv->ByteCount; - } - - if (yv->TextFlag>0) - for (i = 0 ; i <= c-1 ; i++) - { - b = yv->PktIn[3+i]; - if ((b==LF) && (! yv->CRRecv)) - _lwrite(fv->FileHandle,"\015",1); - if (yv->CRRecv && (b!=LF)) - _lwrite(fv->FileHandle,"\012",1); - yv->CRRecv = b==CR; - _lwrite(fv->FileHandle,&b,1); - } - else - _lwrite(fv->FileHandle, &(yv->PktIn[3]), c); - - fv->ByteCount = fv->ByteCount + c; - - SetDlgNum(fv->HWin, IDC_PROTOPKTNUM, yv->PktNumOffset+yv->PktNum); - SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount); - - FTSetTimeOut(fv,yv->TOutLong); - - return TRUE; -} - -// t@CM(local-to-remote)ÉAYMODEMT[o©çf[^ªçêÄ«½Æ«ÉÄÑo³êéB -BOOL YSendPacket(PFileVar fv, PYVar yv, PComVar cv) -{ - BYTE b; - int i; - BOOL SendFlag; - WORD Check; - BYTE firstch, lastrx; - - SendFlag = FALSE; - if (yv->PktBufCount==0) - { - i = YRead1Byte(fv,yv,cv,&b); - do { - if (i==0) return TRUE; - firstch = b; - switch (b) { - case ACK: - // 1ñÚÌEOTMãÌACKóMÅAu1t@CMvÌIíèÆ·éB - if (yv->SendEot) { - yv->SendEot = 0; - - // Mt@CªcÁĢȢêÍAuSÄÌt@Cð]I¹vðÊm·éB - if (!GetNextFname(fv)) { - yv->LastSendEot = 1; - break; - } else { - initialize_file_info(fv, yv); - } - } - - if (! fv->FileOpen) // à¤M·ét@CªÈ¢êÍA³íI¹B - { - fv->Success = TRUE; - return FALSE; - } - else if (yv->PktNumSent==(BYTE)(yv->PktNum+1)) // ÌubNðé - { - yv->PktNum = yv->PktNumSent; - if (yv->PktNum==0) - yv->PktNumOffset = yv->PktNumOffset + 256; - SendFlag = TRUE; - } - break; - - case NAK: - SendFlag = TRUE; - break; - - case CAN: - break; - - case 0x43: // 'C'(43h) - case 0x47: // 'G'(47h) - // 'C'ðó¯æéÆAubNÌMðJn·éB - if ((yv->PktNum==0) && (yv->PktNumOffset==0)) - { - SendFlag = TRUE; - } - else if (yv->LastSendEot) { - SendFlag = TRUE; - } - break; - } - if (! SendFlag) i = YRead1Byte(fv,yv,cv,&b); - } while (!SendFlag); - // reset timeout timer - FTSetTimeOut(fv,TimeOutVeryLong); - - // ã±ÌT[o©çÌf[^ðÇÝÌÄéB - do { - lastrx = firstch; - i = YRead1Byte(fv,yv,cv,&b); - if (i != 0) { - firstch = b; - if (firstch == CAN && lastrx == CAN) { - // CAN(0x18)ªA±µÄéÆAt@CM̸sÆ©È·B - // ½Æ¦ÎAT[oɯ¼Ìt@Cª¶Ý·éêÈÇB - // (2010.3.23 yutaka) - fv->Success = FALSE; // failure - return FALSE; - } - } - } while (i != 0); - - if (yv->LastSendEot) { // I[[ÌubNðMµÄAà¤t@CªÈ¢±Æðmç¹éB - yv->LastSendEot = 0; - - if (yv->DataLen == SOH_DATALEN) - yv->PktOut[0] = SOH; - else - yv->PktOut[0] = STX; - yv->PktOut[1] = 0; - yv->PktOut[2] = ~0; - - i = 0; - while (i < yv->DataLen) - { - yv->PktOut[i+3] = 0x00; - i++; - } - - Check = YCalcCheck(yv,yv->PktOut); - if (yv->CheckLen==1) /* Checksum */ - yv->PktOut[yv->DataLen+3] = (BYTE)Check; - else { - yv->PktOut[yv->DataLen+3] = HIBYTE(Check); - yv->PktOut[yv->DataLen+4] = LOBYTE(Check); - } - yv->PktBufCount = 3 + yv->DataLen + yv->CheckLen; - - } - else if (yv->PktNumSent==yv->PktNum) /* make a new packet */ - { - BYTE *dataptr = &yv->PktOut[3]; - int eot = 0; // End Of Transfer - - if (yv->DataLen == SOH_DATALEN) - yv->PktOut[0] = SOH; - else - yv->PktOut[0] = STX; - yv->PktOut[1] = yv->PktNumSent; - yv->PktOut[2] = ~ yv->PktNumSent; - - // ubNÔÌJEgAbvBYMODEMÅÍ"0"©çJn·éB - yv->PktNumSent++; - - // ubN0 - if (yv->SendFileInfo == 0) { // t@CîñÌM - struct _stat st; - int ret, total; - BYTE buf[1024 + 10]; - - yv->SendFileInfo = 1; // MÏÝtOon - - /* timestamp */ - _stat(fv->FullName, &st); - - ret = _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s", - &(fv->FullName[fv->DirLen])); - buf[ret] = 0x00; // NUL - total = ret + 1; - - ret = _snprintf_s(&(buf[total]), sizeof(buf) - total, _TRUNCATE, "%lu %lo %o", - fv->FileSize, (long)st.st_mtime, 0644|_S_IFREG); - total += ret; - - i = total; - while (i <= yv->DataLen) - { - buf[i] = 0x00; - i++; - } - - // f[^Rs[ - memcpy(dataptr, buf, yv->DataLen); - - } else { - i = 1; - while ((i<=yv->DataLen) && fv->FileOpen && - (_lread(fv->FileHandle,&b,1)==1)) - { - yv->PktOut[2+i] = b; - i++; - fv->ByteCount++; - } - - - if (i>1) - { - while (i<=yv->DataLen) - { - yv->PktOut[2+i] = 0x1A; - i++; - } - - } - else { /* send EOT */ - if (fv->FileOpen) - { - _lclose(fv->FileHandle); - fv->FileHandle = 0; - fv->FileOpen = FALSE; - } - - eot = 1; - } - - } - - if (eot == 0) { // f[^ubN - Check = YCalcCheck(yv,yv->PktOut); - if (yv->CheckLen==1) /* Checksum */ - yv->PktOut[yv->DataLen+3] = (BYTE)Check; - else { - yv->PktOut[yv->DataLen+3] = HIBYTE(Check); - yv->PktOut[yv->DataLen+4] = LOBYTE(Check); - } - yv->PktBufCount = 3 + yv->DataLen + yv->CheckLen; - - } else { // EOT - yv->PktOut[0] = EOT; - yv->PktBufCount = 1; - - yv->SendEot = 1; // EOTtOonBÍNAKðúÒ·éB - yv->LastSendEot = 0; - } - - } - else { /* resend packet */ - yv->PktBufCount = 3 + yv->DataLen + yv->CheckLen; - } - - yv->PktBufPtr = 0; - } - /* a NAK or C could have arrived while we were buffering. Consume it. */ - // ã±ÌT[o©çÌf[^ðÇÝÌÄéB - do { - lastrx = firstch; - i = YRead1Byte(fv,yv,cv,&b); - if (i != 0) { - firstch = b; - if (firstch == CAN && lastrx == CAN) { - // CAN(0x18)ªA±µÄéÆAt@CM̸sÆ©È·B - // ½Æ¦ÎAT[oɯ¼Ìt@Cª¶Ý·éêÈÇB - // (2010.3.23 yutaka) - fv->Success = FALSE; // failure - return FALSE; - } - } - } while (i != 0); - - - i = 1; - while ((yv->PktBufCount>0) && (i>0)) - { - b = yv->PktOut[yv->PktBufPtr]; - i = YWrite(fv,yv,cv,&b, 1); - if (i>0) - { - yv->PktBufCount--; - yv->PktBufPtr++; - } - } - - if (yv->PktBufCount==0) - { - SetDlgNum(fv->HWin, IDC_PROTOPKTNUM, - yv->PktNumOffset+yv->PktNumSent); - SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount); - SetDlgPercent(fv->HWin, IDC_PROTOPERCENT, IDC_PROTOPROGRESS, - fv->ByteCount, fv->FileSize, &fv->ProgStat); - } - - return TRUE; -} +/* Tera Term +Copyright(C) 2008-2010 TeraTerm Project +All rights reserved. */ + +/* TTFILE.DLL, YMODEM protocol */ +#include "teraterm.h" +#include "tttypes.h" +#include "ttftypes.h" +#include <stdio.h> +#include <time.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "tt_res.h" +#include "ttcommon.h" +#include "ttlib.h" +#include "ftlib.h" +#include "dlglib.h" + +#include "ymodem.h" + +#define TimeOutInit 10 +#define TimeOutC 3 +#define TimeOutShort 10 +#define TimeOutLong 20 +#define TimeOutVeryLong 60 + +// f[^]TCYBYMODEMÅÍ 128 or 1024 byte ðT|[g·éB +#define SOH_DATALEN 128 +#define STX_DATALEN 1024 + +int YRead1Byte(PFileVar fv, PYVar yv, PComVar cv, LPBYTE b) +{ + if (CommRead1Byte(cv,b) == 0) + return 0; + + if (fv->LogFlag) + { + if (fv->LogState==0) + { + // cèÌASCII\¦ðs¤ + fv->FlushLogLineBuf = 1; + FTLog1Byte(fv,0); + fv->FlushLogLineBuf = 0; + + fv->LogState = 1; + fv->LogCount = 0; + fv->FlushLogLineBuf = 0; + _lwrite(fv->LogFile,"\015\012<<<\015\012",7); + } + FTLog1Byte(fv,*b); + } + return 1; +} + +int YWrite(PFileVar fv, PYVar yv, PComVar cv, PCHAR B, int C) +{ + int i, j; + + i = CommBinaryOut(cv,B,C); + if (fv->LogFlag && (i>0)) + { + if (fv->LogState != 0) + { + // cèÌASCII\¦ðs¤ + fv->FlushLogLineBuf = 1; + FTLog1Byte(fv,0); + fv->FlushLogLineBuf = 0; + + fv->LogState = 0; + fv->LogCount = 0; + _lwrite(fv->LogFile,"\015\012>>>\015\012",7); + } + for (j=0 ; j <= i-1 ; j++) + FTLog1Byte(fv,B[j]); + } + return i; +} + +void YSetOpt(PFileVar fv, PYVar yv, WORD Opt) +{ + char Tmp[21]; + + yv->YOpt = Opt; + + strncpy_s(Tmp, sizeof(Tmp),"YMODEM (", _TRUNCATE); + switch (yv->YOpt) { + case Yopt1K: /* YMODEM */ + strncat_s(Tmp,sizeof(Tmp),"1k)",_TRUNCATE); + yv->DataLen = 1024; + yv->CheckLen = 2; + break; + case YoptG: /* YMODEM-g */ + strncat_s(Tmp,sizeof(Tmp),"-g)",_TRUNCATE); + yv->DataLen = 1024; + yv->CheckLen = 2; + break; + case YoptSingle: /* YMODEM(-g) single mode */ + strncat_s(Tmp,sizeof(Tmp),"single mode)",_TRUNCATE); + yv->DataLen = 1024; + yv->CheckLen = 2; + break; + } + SetDlgItemText(fv->HWin, IDC_PROTOPROT, Tmp); +} + +void YSendNAK(PFileVar fv, PYVar yv, PComVar cv) +{ + BYTE b; + int t; + + /* flush comm buffer */ + cv->InBuffCount = 0; + cv->InPtr = 0; + + yv->NAKCount--; + if (yv->NAKCount<0) + { + if (yv->NAKMode==YnakC) + { + YSetOpt(fv,yv,XoptCheck); + yv->NAKMode = YnakC; + yv->NAKCount = 9; + } + else { + YCancel(fv,yv,cv); + return; + } + } + + if (yv->NAKMode!=YnakC) + { + b = NAK; + if ((yv->PktNum==0) && (yv->PktNumOffset==0)) + t = TimeOutInit; + else + t = yv->TOutLong; + } + else { + b = 'C'; + t = TimeOutC; + } + YWrite(fv,yv,cv,&b,1); + yv->PktReadMode = XpktSOH; + FTSetTimeOut(fv,t); +} + +WORD YCalcCheck(PYVar yv, PCHAR PktBuf) +{ + int i; + WORD Check; + + if (yv->CheckLen==1) /* CheckSum */ + { + /* Calc sum */ + Check = 0; + for (i = 0 ; i <= yv->DataLen-1 ; i++) + Check = Check + (BYTE)(PktBuf[3+i]); + return (Check & 0xff); + } + else { /* CRC */ + Check = 0; + for (i = 0 ; i <= yv->DataLen-1 ; i++) + Check = UpdateCRC(PktBuf[3+i],Check); + return (Check); + } +} + +BOOL YCheckPacket(PYVar yv) +{ + WORD Check; + + Check = YCalcCheck(yv,yv->PktIn); + if (yv->CheckLen==1) /* Checksum */ + return ((BYTE)Check==yv->PktIn[yv->DataLen+3]); + else + return ((HIBYTE(Check)==yv->PktIn[yv->DataLen+3]) && + (LOBYTE(Check)==yv->PktIn[yv->DataLen+4])); +} + +static void initialize_file_info(PFileVar fv, PYVar yv) +{ + if (yv->YMode == IdYSend) { + if (fv->FileOpen) { + _lclose(fv->FileHandle); + } + fv->FileHandle = _lopen(fv->FullName,OF_READ); + fv->FileSize = GetFSize(fv->FullName); + } else { + fv->FileHandle = -1; + fv->FileSize = 0; + } + fv->FileOpen = fv->FileHandle>0; + + if (yv->YMode == IdYSend) { + InitDlgProgress(fv->HWin, IDC_PROTOPROGRESS, &fv->ProgStat); + } else { + fv->ProgStat = -1; + } + SetDlgItemText(fv->HWin, IDC_PROTOFNAME, &(fv->FullName[fv->DirLen])); + + yv->PktNumOffset = 0; + yv->PktNum = 0; + yv->PktNumSent = 0; + yv->PktBufCount = 0; + yv->CRRecv = FALSE; + fv->ByteCount = 0; + yv->SendFileInfo = 0; + yv->SendEot = 0; + yv->LastSendEot = 0; +} + +void YInit +(PFileVar fv, PYVar yv, PComVar cv, PTTSet ts) +{ + char inistr[MAXPATHLEN + 10]; + + if (yv->YMode == IdYSend) { + if (!GetNextFname(fv)) { + return; + } + } + + fv->LogFlag = ((ts->LogFlag & LOG_Y)!=0); + if (fv->LogFlag) + fv->LogFile = _lcreat("YMODEM.LOG",0); + fv->LogState = 0; + fv->LogCount = 0; + + SetWindowText(fv->HWin, fv->DlgCaption); + + initialize_file_info(fv, yv); + + if (cv->PortType==IdTCPIP) + { + yv->TOutShort = TimeOutVeryLong; + yv->TOutLong = TimeOutVeryLong; + } + else { + yv->TOutShort = TimeOutShort; + yv->TOutLong = TimeOutLong; + } + + YSetOpt(fv,yv,yv->YOpt); + + if (yv->YOpt == Yopt1K) + { + yv->NAKMode = YnakC; + yv->NAKCount = 10; + } + else { + yv->NAKMode = YnakG; + yv->NAKCount = 10; + } + + if (fv->LogFlag) { + char buf[128]; + time_t tm = time(NULL); + + _snprintf_s(buf, sizeof(buf), _TRUNCATE, "YMODEM %s start: %s\n", + yv->YMode == IdYSend ? "Send" : "Recv", + ctime(&tm) + ); + _lwrite(fv->LogFile, buf, strlen(buf)); + } + + switch (yv->YMode) { + case IdYSend: + yv->TextFlag = 0; + + // t@CMJnOÉA"rb t@C¼"ð©®IÉÄÑo·B(2007.12.20 yutaka) + //strcpy(ts->YModemRcvCommand, "rb"); + if (ts->YModemRcvCommand[0] != '\0') { + _snprintf_s(inistr, sizeof(inistr), _TRUNCATE, "%s\015", + ts->YModemRcvCommand); + YWrite(fv,yv,cv, inistr , strlen(inistr)); + } + + FTSetTimeOut(fv,TimeOutVeryLong); + break; + + case IdYReceive: +#if 0 // for debug + strcpy(inistr, "sb -b svnrev.exe lrzsz-0.12.20.tar.gz\r\n"); +// strcpy(inistr, "sb url3.txt url4.txt url5.txt\r\n"); + YWrite(fv,yv,cv, inistr , strlen(inistr)); +#endif + yv->TextFlag = 0; + + YSendNAK(fv,yv,cv); + + break; + } +} + +void YCancel(PFileVar fv, PYVar yv, PComVar cv) +{ + // five cancels & five backspaces per spec + BYTE cancel[] = { CAN, CAN, CAN, CAN, CAN, BS, BS, BS, BS, BS }; + + YWrite(fv,yv,cv, (PCHAR)&cancel, sizeof(cancel)); + yv->YMode = 0; // quit +} + +void YTimeOutProc(PFileVar fv, PYVar yv, PComVar cv) +{ + switch (yv->YMode) { + case IdXSend: + yv->YMode = 0; // quit + break; + case IdXReceive: + YSendNAK(fv,yv,cv); + break; + } +} + +// YMODEMT[o©çt@CðóM·éÛAProtoParse()©çÄÑo³êéÖB +// +// +-------+-------+--------+---------+-----+ +// |Header |Block# |1-Block#| Payload | CRC | +// +-------+-------+--------+---------+-----+ +// 1 1 1 128/1024 2 byte +// +// return TRUE: t@CóM +// FALSE: óM®¹ +BOOL YReadPacket(PFileVar fv, PYVar yv, PComVar cv) +{ + BYTE b, d; + int i, c, nak; + BOOL GetPkt; + + c = YRead1Byte(fv,yv,cv,&b); + + GetPkt = FALSE; + + while ((c>0) && (! GetPkt)) + { + switch (yv->PktReadMode) { + case XpktSOH: + // SOH © STX ©ÅubN·ªÜéB + if (b==SOH) + { + yv->PktIn[0] = b; + yv->PktReadMode = XpktBLK; + yv->DataLen = SOH_DATALEN; + FTSetTimeOut(fv,yv->TOutShort); + } + else if (b==STX) + { + yv->PktIn[0] = b; + yv->PktReadMode = XpktBLK; + yv->DataLen = STX_DATALEN; + FTSetTimeOut(fv,yv->TOutShort); + } + else if (b==EOT) + { + // EOTª½çA1ÂÌt@CóMª®¹µ½±Æð¦·B + if (fv->FileOpen) { + fv->FileOpen = 0; + _lclose(fv->FileHandle); + fv->FileHandle = -1; + } + + initialize_file_info(fv, yv); + + // EOTÉεÄACKðÔ· + b = ACK; + YWrite(fv,yv,cv,&b, 1); + + // Ìt@CM𣷽ßA'C'ðéB + YSendNAK(fv,yv,cv); + + return TRUE; + } + else { + /* flush comm buffer */ + cv->InBuffCount = 0; + cv->InPtr = 0; + return TRUE; + } + break; + case XpktBLK: + yv->PktIn[1] = b; + yv->PktReadMode = XpktBLK2; + FTSetTimeOut(fv,yv->TOutShort); + break; + case XpktBLK2: + nak = 1; + yv->PktIn[2] = b; + if ((b ^ yv->PktIn[1]) == 0xff) { + nak = 0; + if (yv->SendFileInfo) { + if (yv->PktIn[1] == (BYTE)(yv->PktNum + 1)) // ÌubNÔ© + nak = 0; + } + } + + if (nak == 0) + { + yv->PktBufPtr = 3; + yv->PktBufCount = yv->DataLen + yv->CheckLen; + yv->PktReadMode = XpktDATA; + FTSetTimeOut(fv,yv->TOutShort); + } + else + YSendNAK(fv,yv,cv); + break; + case XpktDATA: + yv->PktIn[yv->PktBufPtr] = b; + yv->PktBufPtr++; + yv->PktBufCount--; + GetPkt = yv->PktBufCount==0; + if (GetPkt) + { + FTSetTimeOut(fv,yv->TOutLong); + yv->PktReadMode = XpktSOH; + } + else + FTSetTimeOut(fv,yv->TOutShort); + break; + } + + if (! GetPkt) c = YRead1Byte(fv,yv,cv,&b); + } + + if (! GetPkt) return TRUE; + + GetPkt = YCheckPacket(yv); + if (! GetPkt) + { + YSendNAK(fv,yv,cv); + return TRUE; + } + + // I[[ÈçÎASt@CóMÌ®¹ð¦·B + if (yv->PktIn[1] == 0x00 && yv->PktIn[2] == 0xFF && + yv->SendFileInfo == 0 + ) { + c = yv->DataLen; + while ((c>0) && (yv->PktIn[2+c]==0x00)) + c--; + if (c == 0) { + b = ACK; + YWrite(fv,yv,cv,&b, 1); + fv->Success = TRUE; + return FALSE; + } + } + + d = yv->PktIn[1] - yv->PktNum; + if (d>1) + { + YCancel(fv,yv,cv); + return FALSE; + } + + /* send ACK */ + b = ACK; + YWrite(fv,yv,cv,&b, 1); + yv->NAKMode = YnakC; + yv->NAKCount = 10; + + // d¡µÄ¢éêÍA½àµÈ¢B + if (yv->SendFileInfo && + yv->PktIn[1] == (BYTE)(yv->PktNum)) { + return TRUE; + } + + yv->PktNum = yv->PktIn[1]; + + // YMODEMÌêAblock#0ªut@CîñvÆÈéB + if (d == 0 && + yv->SendFileInfo == 0) { + long modtime; + long bytes_total; + int mode; + int ret; + BYTE *p; + char *name, *nameend; + + p = &(yv->PktIn[3]); + name = p; + strncpy_s(fv->FullName, sizeof(fv->FullName), name, _TRUNCATE); + nameend = name + 1 + strlen(name); + if (*nameend) { + ret = sscanf(nameend, "%ld%lo%o", &bytes_total, &modtime, &mode); + if (ret == 3) { + fv->FileSize = bytes_total; + } + } + fv->FileHandle = _lcreat(fv->FullName,0); + fv->FileOpen = fv->FileHandle>0; + + fv->DirLen = 0; + SetDlgItemText(fv->HWin, IDC_PROTOFNAME, &(fv->FullName[fv->DirLen])); + + yv->SendFileInfo = 1; + + return TRUE; + } + + if (yv->PktNum==0) + yv->PktNumOffset = yv->PktNumOffset + 256; + + c = yv->DataLen; + if (yv->TextFlag>0) + while ((c>0) && (yv->PktIn[2+c]==0x1A)) + c--; + + // ÅIubNÌ]ªÈf[^ð·é + if (fv->ByteCount + c > fv->FileSize) { + c = fv->FileSize - fv->ByteCount; + } + + if (yv->TextFlag>0) + for (i = 0 ; i <= c-1 ; i++) + { + b = yv->PktIn[3+i]; + if ((b==LF) && (! yv->CRRecv)) + _lwrite(fv->FileHandle,"\015",1); + if (yv->CRRecv && (b!=LF)) + _lwrite(fv->FileHandle,"\012",1); + yv->CRRecv = b==CR; + _lwrite(fv->FileHandle,&b,1); + } + else + _lwrite(fv->FileHandle, &(yv->PktIn[3]), c); + + fv->ByteCount = fv->ByteCount + c; + + SetDlgNum(fv->HWin, IDC_PROTOPKTNUM, yv->PktNumOffset+yv->PktNum); + SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount); + + FTSetTimeOut(fv,yv->TOutLong); + + return TRUE; +} + +// t@CM(local-to-remote)ÉAYMODEMT[o©çf[^ªçêÄ«½Æ«ÉÄÑo³êéB +BOOL YSendPacket(PFileVar fv, PYVar yv, PComVar cv) +{ + BYTE b; + int i; + BOOL SendFlag; + WORD Check; + BYTE firstch, lastrx; + + SendFlag = FALSE; + if (yv->PktBufCount==0) + { + i = YRead1Byte(fv,yv,cv,&b); + do { + if (i==0) return TRUE; + firstch = b; + switch (b) { + case ACK: + // 1ñÚÌEOTMãÌACKóMÅAu1t@CMvÌIíèÆ·éB + if (yv->SendEot) { + yv->SendEot = 0; + + // Mt@CªcÁĢȢêÍAuSÄÌt@Cð]I¹vðÊm·éB + if (!GetNextFname(fv)) { + yv->LastSendEot = 1; + break; + } else { + initialize_file_info(fv, yv); + } + } + + if (! fv->FileOpen) // à¤M·ét@CªÈ¢êÍA³íI¹B + { + fv->Success = TRUE; + return FALSE; + } + else if (yv->PktNumSent==(BYTE)(yv->PktNum+1)) // ÌubNðé + { + yv->PktNum = yv->PktNumSent; + if (yv->PktNum==0) + yv->PktNumOffset = yv->PktNumOffset + 256; + SendFlag = TRUE; + } + break; + + case NAK: + SendFlag = TRUE; + break; + + case CAN: + break; + + case 0x43: // 'C'(43h) + case 0x47: // 'G'(47h) + // 'C'ðó¯æéÆAubNÌMðJn·éB + if ((yv->PktNum==0) && (yv->PktNumOffset==0)) + { + SendFlag = TRUE; + } + else if (yv->LastSendEot) { + SendFlag = TRUE; + } + break; + } + if (! SendFlag) i = YRead1Byte(fv,yv,cv,&b); + } while (!SendFlag); + + // reset timeout timer + FTSetTimeOut(fv,TimeOutVeryLong); + + // ã±ÌT[o©çÌf[^ðÇÝÌÄéB + do { + lastrx = firstch; + i = YRead1Byte(fv,yv,cv,&b); + if (i != 0) { + firstch = b; + if (firstch == CAN && lastrx == CAN) { + // CAN(0x18)ªA±µÄéÆAt@CM̸sÆ©È·B + // ½Æ¦ÎAT[oɯ¼Ìt@Cª¶Ý·éêÈÇB + // (2010.3.23 yutaka) + fv->Success = FALSE; // failure + return FALSE; + } + } + } while (i != 0); + + if (yv->LastSendEot) { // I[[ÌubNðMµÄAà¤t@CªÈ¢±Æðmç¹éB + yv->LastSendEot = 0; + + if (yv->DataLen == SOH_DATALEN) + yv->PktOut[0] = SOH; + else + yv->PktOut[0] = STX; + yv->PktOut[1] = 0; + yv->PktOut[2] = ~0; + + i = 0; + while (i < yv->DataLen) + { + yv->PktOut[i+3] = 0x00; + i++; + } + + Check = YCalcCheck(yv,yv->PktOut); + if (yv->CheckLen==1) /* Checksum */ + yv->PktOut[yv->DataLen+3] = (BYTE)Check; + else { + yv->PktOut[yv->DataLen+3] = HIBYTE(Check); + yv->PktOut[yv->DataLen+4] = LOBYTE(Check); + } + yv->PktBufCount = 3 + yv->DataLen + yv->CheckLen; + //fv->Success = TRUE; + + } + else if (yv->PktNumSent==yv->PktNum) /* make a new packet */ + { + BYTE *dataptr = &yv->PktOut[3]; + int eot = 0; // End Of Transfer + + if (yv->DataLen == SOH_DATALEN) + yv->PktOut[0] = SOH; + else + yv->PktOut[0] = STX; + yv->PktOut[1] = yv->PktNumSent; + yv->PktOut[2] = ~ yv->PktNumSent; + + // ubNÔÌJEgAbvBYMODEMÅÍ"0"©çJn·éB + yv->PktNumSent++; + + // ubN0 + if (yv->SendFileInfo == 0) { // t@CîñÌM + struct _stat st; + int ret, total; + BYTE buf[1024 + 10]; + + yv->SendFileInfo = 1; // MÏÝtOon + + /* timestamp */ + _stat(fv->FullName, &st); + + ret = _snprintf_s(buf, sizeof(buf), _TRUNCATE, "%s", + &(fv->FullName[fv->DirLen])); + buf[ret] = 0x00; // NUL + total = ret + 1; + + ret = _snprintf_s(&(buf[total]), sizeof(buf) - total, _TRUNCATE, "%lu %lo %o", + fv->FileSize, (long)st.st_mtime, 0644|_S_IFREG); + total += ret; + + i = total; + while (i <= yv->DataLen) + { + buf[i] = 0x00; + i++; + } + + // f[^Rs[ + memcpy(dataptr, buf, yv->DataLen); + + } else { + i = 1; + while ((i<=yv->DataLen) && fv->FileOpen && + (_lread(fv->FileHandle,&b,1)==1)) + { + yv->PktOut[2+i] = b; + i++; + fv->ByteCount++; + } + + + if (i>1) + { + while (i<=yv->DataLen) + { + yv->PktOut[2+i] = 0x1A; + i++; + } + + } + else { /* send EOT */ + if (fv->FileOpen) + { + _lclose(fv->FileHandle); + fv->FileHandle = 0; + fv->FileOpen = FALSE; + } + + eot = 1; + } + + } + + if (eot == 0) { // f[^ubN + Check = YCalcCheck(yv,yv->PktOut); + if (yv->CheckLen==1) /* Checksum */ + yv->PktOut[yv->DataLen+3] = (BYTE)Check; + else { + yv->PktOut[yv->DataLen+3] = HIBYTE(Check); + yv->PktOut[yv->DataLen+4] = LOBYTE(Check); + } + yv->PktBufCount = 3 + yv->DataLen + yv->CheckLen; + + } else { // EOT + yv->PktOut[0] = EOT; + yv->PktBufCount = 1; + + yv->SendEot = 1; // EOTtOonBÍNAKðúÒ·éB + yv->LastSendEot = 0; + } + + } + else { /* resend packet */ + yv->PktBufCount = 3 + yv->DataLen + yv->CheckLen; + } + + yv->PktBufPtr = 0; + } + /* a NAK or C could have arrived while we were buffering. Consume it. */ + // ã±ÌT[o©çÌf[^ðÇÝÌÄéB + do { + lastrx = firstch; + i = YRead1Byte(fv,yv,cv,&b); + if (i != 0) { + firstch = b; + if (firstch == CAN && lastrx == CAN) { + // CAN(0x18)ªA±µÄéÆAt@CM̸sÆ©È·B + // ½Æ¦ÎAT[oɯ¼Ìt@Cª¶Ý·éêÈÇB + // (2010.3.23 yutaka) + fv->Success = FALSE; // failure + return FALSE; + } + } + } while (i != 0); + + + i = 1; + while ((yv->PktBufCount>0) && (i>0)) + { + b = yv->PktOut[yv->PktBufPtr]; + i = YWrite(fv,yv,cv,&b, 1); + if (i>0) + { + yv->PktBufCount--; + yv->PktBufPtr++; + } + } + + if (yv->PktBufCount==0) + { + SetDlgNum(fv->HWin, IDC_PROTOPKTNUM, + yv->PktNumOffset+yv->PktNumSent); + SetDlgNum(fv->HWin, IDC_PROTOBYTECOUNT, fv->ByteCount); + SetDlgPercent(fv->HWin, IDC_PROTOPERCENT, IDC_PROTOPROGRESS, + fv->ByteCount, fv->FileSize, &fv->ProgStat); + } + + return TRUE; +}