1384 lines
36 KiB
C
1384 lines
36 KiB
C
/*
|
|
commands.c
|
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
Implementation of Telnet Commands
|
|
*/
|
|
|
|
#pragma warning( disable: 4201 )
|
|
#pragma warning( disable: 4100 )
|
|
|
|
#include <windows.h> /* required for all Windows applications */
|
|
#include <tchar.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <winsock2.h>
|
|
#include "commands.h"
|
|
#include "WinTel.h" /* specific to this program */
|
|
#include "debug.h"
|
|
#include "trmio.h"
|
|
#include "telnet.h"
|
|
|
|
extern WI gwi;
|
|
extern HINSTANCE ghInstance;
|
|
extern HANDLE g_hRemoteNEscapeModeDataSync;
|
|
extern HANDLE g_hCaptureConsoleEvent;
|
|
extern WCHAR g_szKbdEscape[];
|
|
extern BOOL g_bIsEscapeCharValid;
|
|
extern BOOL bDoVtNTFirstTime;
|
|
extern BOOL fPrintMessageToSessionConsole;
|
|
BOOL bOnlyOnce = 1;
|
|
BOOL bBufferSizeChanged = 0;
|
|
BOOL bWindowSizeChanged = 0;
|
|
BOOL bMaxWindow = 0;
|
|
extern SMALL_RECT srOldClientWindow;
|
|
extern TCHAR g_szLogFile[];
|
|
extern g_fSentWillNaws;
|
|
void SetWindowSize( HANDLE );
|
|
void GetErrMsgString( DWORD, LPTSTR* );
|
|
|
|
BOOL StuffEscapeIACs( PUCHAR* ppBufDest, UCHAR bufSrc[], DWORD* pdwSize );
|
|
|
|
void ConvertAndSendVTNTData( LPTSTR pData, int iLen );
|
|
|
|
void *SfuZeroMemory(
|
|
void *ptr,
|
|
unsigned int cnt
|
|
)
|
|
{
|
|
volatile char *vptr = (volatile char *)ptr;
|
|
|
|
while (cnt)
|
|
{
|
|
*vptr = 0;
|
|
vptr ++;
|
|
cnt --;
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
BOOL PromptUser()
|
|
{
|
|
DWORD dwLength = 1;
|
|
INPUT_RECORD irRec;
|
|
|
|
ResetEvent( g_hCaptureConsoleEvent );
|
|
ui.bPromptForNtlm = TRUE;
|
|
irRec.EventType = FOCUS_EVENT;
|
|
irRec.Event.FocusEvent.bSetFocus = TRUE;
|
|
WriteConsoleInput( gwi.hInput, &irRec, dwLength, &dwLength );
|
|
|
|
WaitForSingleObject( g_hCaptureConsoleEvent, INFINITE );
|
|
|
|
return ui.bSendCredsToRemoteSite;
|
|
}
|
|
|
|
//NULL as the last arg is a MUST when you are using Write function
|
|
void Write(LPTSTR lpszFmtStr, ...)
|
|
{
|
|
DWORD dwWritten;
|
|
DWORD dwSize = 0;
|
|
va_list vaArgList;
|
|
TCHAR *szBuf = NULL;
|
|
TCHAR *szArg = lpszFmtStr;
|
|
|
|
if( !lpszFmtStr )
|
|
{
|
|
return;
|
|
}
|
|
|
|
va_start( vaArgList, lpszFmtStr );
|
|
while( szArg )
|
|
{
|
|
dwSize += wcslen( szArg );
|
|
szArg = va_arg( vaArgList, LPWSTR );
|
|
}
|
|
|
|
va_end( vaArgList );
|
|
|
|
szBuf = ( TCHAR *) malloc( ( dwSize + 1 ) * sizeof( TCHAR ) );
|
|
if( !szBuf )
|
|
{
|
|
return;
|
|
}
|
|
szBuf[dwSize] = 0;
|
|
va_start( vaArgList, lpszFmtStr );
|
|
//PREFIX gives "untrusted function". We want to use _vsntprintf(). Won't fix.
|
|
_vsntprintf( szBuf, dwSize,lpszFmtStr, vaArgList );
|
|
va_end( vaArgList );
|
|
WriteConsole(gwi.hOutput, szBuf, _tcslen(szBuf), &dwWritten, NULL);
|
|
|
|
free( szBuf );
|
|
}
|
|
|
|
void WriteMessage( DWORD dwMsgId, WCHAR szEnglishString[] )
|
|
{
|
|
WCHAR szMsg[ MAX_STRING_LENGTH ];
|
|
|
|
if( !LoadString( ghInstance, dwMsgId, szMsg, MAX_STRING_LENGTH ) )
|
|
{
|
|
lstrcpyn( szMsg, szEnglishString, MAX_STRING_LENGTH - sizeof(WCHAR) );
|
|
}
|
|
|
|
Write( szMsg, NULL );
|
|
}
|
|
|
|
|
|
void FreeLoggingDataStructs()
|
|
{
|
|
if( g_rgciCharInfo != NULL )
|
|
(void)LocalFree( (HLOCAL)g_rgciCharInfo );
|
|
|
|
if (g_rgchRow != NULL)
|
|
(void)LocalFree( (HLOCAL)g_rgchRow );
|
|
|
|
g_rgchRow = NULL;
|
|
g_rgciCharInfo = NULL;
|
|
}
|
|
|
|
|
|
BOOL CloseTelnetSession(LPTSTR szCommand)
|
|
{
|
|
CONSOLE_SCREEN_BUFFER_INFO csbInfo;
|
|
|
|
if( FGetCodeMode(eCodeModeIMEFarEast) && bOnlyOnce )
|
|
{
|
|
bOnlyOnce = 0;
|
|
GetConsoleScreenBufferInfo( g_hSessionConsoleBuffer, &csbInfo );
|
|
|
|
if( bBufferSizeChanged )
|
|
{
|
|
csbInfo.dwSize.Y -= 1;
|
|
SetConsoleScreenBufferSize( g_hSessionConsoleBuffer,
|
|
csbInfo.dwSize );
|
|
}
|
|
if( bWindowSizeChanged )
|
|
{
|
|
csbInfo.srWindow.Bottom -= 1;
|
|
SetConsoleWindowInfo( g_hSessionConsoleBuffer, TRUE,
|
|
&csbInfo.srWindow);
|
|
}
|
|
}
|
|
bDoVtNTFirstTime = 1;
|
|
if( fConnected )
|
|
{
|
|
fConnected = FHangupConnection(&gwi, &(gwi.nd));
|
|
}
|
|
|
|
if( ui.bLogging )
|
|
{
|
|
FreeLoggingDataStructs();
|
|
}
|
|
ui.dwMaxRow = 0;
|
|
ui.dwMaxCol = 0;
|
|
|
|
srOldClientWindow.Left = srOldClientWindow.Right = 0;
|
|
srOldClientWindow.Top = srOldClientWindow.Bottom = 0;
|
|
|
|
SetEvent( g_hRemoteNEscapeModeDataSync );
|
|
|
|
SetConsoleTitle( szAppName );
|
|
|
|
g_fSentWillNaws = FALSE; //so that it does naws when we connect again.
|
|
return FALSE;
|
|
}
|
|
|
|
extern CHAR* rgchTermType[];
|
|
|
|
BOOL DisplayParameters(LPTSTR szCommand)
|
|
{
|
|
TCHAR szTermType[81];
|
|
DWORD dwLen = 0;
|
|
|
|
SfuZeroMemory(szTermType, sizeof(szTermType));
|
|
|
|
if( g_bIsEscapeCharValid )
|
|
{
|
|
Write( g_szKbdEscape, NULL );
|
|
}
|
|
else
|
|
{
|
|
TCHAR szMsg[ MAX_STRING_LENGTH ];
|
|
LoadString( ghInstance, IDS_NO_ESCAPE , szMsg, MAX_STRING_LENGTH );
|
|
Write( szMsg, NULL );
|
|
}
|
|
|
|
if ( ui.bWillAUTH )
|
|
Write( szWillAuth, NULL );
|
|
else
|
|
Write( szWontAuth, NULL );
|
|
|
|
if( ui.fDebug & fdwLocalEcho )
|
|
Write( szLocalEchoOn, NULL );
|
|
else
|
|
Write( szLocalEchoOff, NULL );
|
|
|
|
if( ui.bLogging )
|
|
{
|
|
TCHAR szFileNameTitle[ MAX_STRING_LENGTH + 1 ];
|
|
WriteMessage( IDS_LOGGING_ON, ( LPTSTR ) TEXT( MSG_LOGGING_ON ) );
|
|
LoadString( ghInstance, IDS_LOGFILE_NAME, szFileNameTitle, MAX_STRING_LENGTH );
|
|
Write( szFileNameTitle, g_szLogFile, NULL );
|
|
}
|
|
|
|
if( ui.dwCrLf )
|
|
{
|
|
WriteMessage( IDS_CRLF, ( LPTSTR ) _T( MSG_CRLF ) );
|
|
}
|
|
else
|
|
{
|
|
WriteMessage( IDS_CR, ( LPTSTR ) _T( MSG_CR ) );
|
|
}
|
|
if( g_bSendBackSpaceAsDel )
|
|
{
|
|
WriteMessage( IDS_BACKSPACEASDEL, ( LPTSTR ) _T( MSG_BACKSPACEASDEL ) );
|
|
}
|
|
if( g_bSendDelAsBackSpace )
|
|
{
|
|
WriteMessage( IDS_DELASBACKSPACE, ( LPTSTR ) _T( MSG_DELASBACKSPACE ) );
|
|
}
|
|
|
|
if( (FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) &&
|
|
FIsVT80(&gwi.trm) && (gwi.trm.RequestedTermType != TT_VTNT) )
|
|
{
|
|
int i =0;
|
|
|
|
for(i=0 ; i<NUMBER_OF_KANJI ; ++i)
|
|
{
|
|
if( gwi.trm.dwKanjiFlags & KanjiList[i].KanjiEmulationID )
|
|
{
|
|
Write( szVT100KanjiEmulation, NULL );
|
|
Write( KanjiList[i].KanjiDescription, NULL );
|
|
break;
|
|
}
|
|
}
|
|
|
|
Write( TEXT("\n"), NULL );
|
|
}
|
|
|
|
{
|
|
DWORD dwSize = 0;
|
|
WCHAR wchTemp[1] = {0L};
|
|
dwSize = GetEnvironmentVariable( TEXT( SFUTLNTMODE ), wchTemp, 0 );
|
|
if( dwSize > 0 )
|
|
{
|
|
TCHAR *szMode = NULL;
|
|
szMode = ( TCHAR * ) malloc( ( dwSize + 1 )* sizeof( TCHAR ) );
|
|
if( szMode != NULL )
|
|
{
|
|
dwSize = GetEnvironmentVariable( TEXT( SFUTLNTMODE ), szMode, dwSize + 1 );
|
|
if( _tcsicmp( szMode, TEXT( CONSOLE )) == 0 )
|
|
{
|
|
dwSize = 0; //indicating console mode
|
|
}
|
|
else
|
|
{
|
|
WriteMessage( IDS_CURRENT_MODE, ( LPTSTR )TEXT( MSG_CURRENT_MODE ) );
|
|
WriteMessage( IDS_STREAM_ONLY, ( LPTSTR )TEXT( MSG_STREAM_ONLY ) );
|
|
}
|
|
free( szMode );
|
|
}
|
|
}
|
|
|
|
if( dwSize == 0 )
|
|
{
|
|
//console mode
|
|
WriteMessage( IDS_CURRENT_MODE, ( LPTSTR )TEXT( MSG_CURRENT_MODE ) );
|
|
WriteMessage( IDS_CONSOLE_ONLY, ( LPTSTR )TEXT( MSG_CONSOLE_ONLY ) );
|
|
}
|
|
}
|
|
|
|
//#if defined(FE_IME)
|
|
// if( ui.fDebug & fdwEnableIMESupport )
|
|
// {
|
|
// Write( szEnableIMEOn, NULL );
|
|
// }
|
|
//#endif /* FE_IME */
|
|
dwLen = sizeof(szTermType)/sizeof(WCHAR);
|
|
szTermType[dwLen -1] = 0;
|
|
_snwprintf( szTermType,dwLen -1, ( LPTSTR )TEXT("%S"), rgchTermType[gwi.trm.RequestedTermType] );
|
|
Write( szPrefTermType, szTermType, NULL );
|
|
|
|
// when we are connected we need to say what we are connected at.
|
|
if ( fConnected && gwi.trm.SentTermType != TT_UNKNOWN )
|
|
{
|
|
_snwprintf( szTermType,(sizeof(szTermType)/sizeof(WCHAR))-1, ( LPTSTR )TEXT("%S"), rgchTermType[gwi.trm.SentTermType]);
|
|
Write( szNegoTermType, szTermType, NULL );
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/* This initialization happens on every OpenTelnetSession()
|
|
and the meemory is freed on every CloseTelnetSession() */
|
|
BOOL InitLoggingDataStructs()
|
|
{
|
|
UINT uiSize = 0;
|
|
|
|
if( g_rgchRow )
|
|
{
|
|
//This is needed because rows and cols may have changed
|
|
FreeLoggingDataStructs();
|
|
}
|
|
|
|
uiSize = (UINT)(sizeof(CHAR_INFO) * ui.dwMaxCol);
|
|
|
|
if( FGetCodeMode( eCodeModeFarEast ) )
|
|
{
|
|
uiSize *= 3; // accounting for a lot of multi byte chars
|
|
}
|
|
|
|
g_rgciCharInfo = (PCHAR_INFO)LocalAlloc(LPTR, uiSize );
|
|
g_rgchRow = (UCHAR *)LocalAlloc(LPTR, uiSize );
|
|
|
|
if ( !g_rgchRow || !g_rgciCharInfo )
|
|
{
|
|
ui.bLogging = FALSE;
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CloseLogging()
|
|
{
|
|
CloseHandle(ui.hLogFile);
|
|
ui.hLogFile = NULL;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL StopLogging()
|
|
{
|
|
ui.bLogging = FALSE;
|
|
FreeLoggingDataStructs();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL InitLogFile( LPTSTR szCommand )
|
|
{
|
|
if( ui.hLogFile )
|
|
{
|
|
CloseLogging( );
|
|
}
|
|
|
|
ui.hLogFile = CreateFile( szCommand, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL,
|
|
CREATE_ALWAYS, 0, NULL);
|
|
if (ui.hLogFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
LPWSTR szErrMsg = NULL;
|
|
ui.bLogging = FALSE;
|
|
ui.hLogFile = NULL;
|
|
GetErrMsgString( GetLastError(), &szErrMsg );
|
|
Write( szErrMsg, L"\r\n", NULL );
|
|
LocalFree( szErrMsg );
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL StartLogging( )
|
|
{
|
|
ui.bLogging = FALSE;
|
|
if( !ui.hLogFile ) //If we have valid logfile
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
ui.bLogging = TRUE;
|
|
|
|
if( ui.dwMaxRow != 0 && ui.dwMaxCol != 0 )
|
|
{
|
|
InitLoggingDataStructs();
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
INT GetRequestedTermType( LPTSTR pszTerm )
|
|
{
|
|
if( !_tcsicmp( pszTerm, ( LPTSTR )TEXT("ansi") ))
|
|
return 0;
|
|
if( !_tcsicmp( pszTerm, ( LPTSTR )TEXT("vt100") ))
|
|
return 1;
|
|
if( !_tcsicmp( pszTerm, ( LPTSTR )TEXT("vt52") ))
|
|
return 2;
|
|
if( !_tcsicmp( pszTerm, ( LPTSTR )TEXT("vtnt") ))
|
|
return 3;
|
|
|
|
return -1;
|
|
}
|
|
|
|
void SqueezeWhiteSpace( TCHAR s[] )
|
|
{
|
|
INT i,j;
|
|
|
|
if( s == NULL )
|
|
{
|
|
return;
|
|
}
|
|
|
|
for( i = 0, j= 0; s[i] != _T('\0'); i++ )
|
|
if( !iswspace( s[i] ) )
|
|
{
|
|
s[j++] = s[i];
|
|
}
|
|
s[j] = _T('\0');
|
|
}
|
|
|
|
void RemoveLeadingNTrailingWhiteSpaces( LPTSTR *pOption )
|
|
{
|
|
DWORD dwIndex = 0;
|
|
|
|
if( *pOption == NULL )
|
|
{
|
|
return;
|
|
}
|
|
|
|
dwIndex = wcslen( *pOption );
|
|
if( dwIndex <= 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
while( iswspace( (*pOption)[ dwIndex - 1 ] ) && dwIndex > 0 )
|
|
{
|
|
dwIndex--;
|
|
}
|
|
|
|
(*pOption)[ dwIndex ] = L'\0';
|
|
|
|
while( iswspace( *( *pOption ) ) )
|
|
{
|
|
(*pOption)++;
|
|
}
|
|
|
|
}
|
|
|
|
BOOL SendOptions( LPTSTR pOption )
|
|
{
|
|
|
|
if( pOption == NULL )
|
|
{
|
|
WriteMessage( IDS_SEND_FORMAT, ( LPTSTR )TEXT( MSG_SEND_FORMAT ) );
|
|
return FALSE;
|
|
}
|
|
|
|
RemoveLeadingNTrailingWhiteSpaces( &pOption );
|
|
|
|
if( *pOption== _T('?') )
|
|
{
|
|
WriteMessage( IDS_SEND_HELP, ( LPTSTR )TEXT( MSG_SEND_HELP ) );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !fConnected )
|
|
{
|
|
WriteMessage( IDS_NOT_CONNECTED, ( LPTSTR )TEXT( MSG_NOT_CONNECTED ) );
|
|
return FALSE;
|
|
}
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("AO") ) )
|
|
{
|
|
/* Our server does nothing on receiving AO. This is for other servers */
|
|
FSendTelnetCommands(gwi.hwnd, (char)AO);
|
|
WriteMessage( IDS_SENT_AO, ( LPTSTR )TEXT( MSG_SENT_AO ) );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("AYT") ) )
|
|
{
|
|
FSendTelnetCommands(gwi.hwnd, (char)AYT);
|
|
WriteMessage( IDS_SENT_AYT, ( LPTSTR )TEXT( MSG_SENT_AYT ) );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("ESC") ) )
|
|
{
|
|
if(gwi.trm.CurrentTermType == TT_VTNT)
|
|
{
|
|
ConvertAndSendVTNTData(&g_chEsc,1);
|
|
}
|
|
else
|
|
{
|
|
FSendChars( gwi.hwnd, &g_chEsc, sizeof( g_chEsc ) / sizeof( WCHAR ) );
|
|
}
|
|
WriteMessage( IDS_SENT_ESC, ( LPTSTR )TEXT( MSG_SENT_ESC ) );
|
|
return FALSE;;
|
|
}
|
|
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("IP") ) )
|
|
{
|
|
FSendTelnetCommands(gwi.hwnd, (char)IP);
|
|
WriteMessage( IDS_SENT_IP, ( LPTSTR )TEXT( MSG_SENT_IP ) );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("SYNCH") ) )
|
|
{
|
|
FSendSynch( gwi.hwnd );
|
|
WriteMessage( IDS_SENT_SYNCH, ( LPTSTR )TEXT( MSG_SENT_SYNCH ) );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("BRK") ) )
|
|
{
|
|
FSendTelnetCommands(gwi.hwnd, (char)BREAK );
|
|
WriteMessage( IDS_SENT_BRK, ( LPTSTR )TEXT( MSG_SENT_BRK ) );
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//If none of the above send as it is
|
|
{
|
|
WCHAR szMsg[ MAX_STRING_LENGTH + 1 ];
|
|
if(gwi.trm.CurrentTermType == TT_VTNT)
|
|
{
|
|
ConvertAndSendVTNTData(pOption,wcslen(pOption));
|
|
}
|
|
else
|
|
{
|
|
FSendChars( gwi.hwnd, pOption, wcslen( pOption ) );
|
|
}
|
|
|
|
if( !LoadString( ghInstance, IDS_SENT_CHARS, szMsg, MAX_STRING_LENGTH ) )
|
|
{
|
|
wcscpy( szMsg, TEXT( MSG_SENT_CHARS ) ); //no overflow. LoadString will return NULL terminated string.
|
|
}
|
|
|
|
Write( szMsg, pOption, NULL );
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*++ If the data to be sent to the server is VTNT data, it cannot be sent as it is. This function
|
|
will convert the given string ( pData ) into INPUT_RECORDS and send it through the socket. This
|
|
is needed since the server expects VTNT data in INPUT_RECORD format and not in characters.
|
|
--*/
|
|
void ConvertAndSendVTNTData( LPTSTR pData, int iLen )
|
|
{
|
|
INPUT_RECORD sInputRecord;
|
|
|
|
PUCHAR destBuf = NULL;
|
|
DWORD dwSize = 0;
|
|
int iIndex = 0;
|
|
|
|
while(iLen)
|
|
{
|
|
sInputRecord.EventType = KEY_EVENT;
|
|
sInputRecord.Event.KeyEvent.bKeyDown = TRUE;
|
|
sInputRecord.Event.KeyEvent.uChar.UnicodeChar = pData[iIndex];
|
|
|
|
dwSize = sizeof( INPUT_RECORD );
|
|
if( !StuffEscapeIACs( &destBuf, (PUCHAR) &sInputRecord, &dwSize ) )
|
|
{
|
|
FWriteToNet(&gwi, (char *)&sInputRecord, sizeof(INPUT_RECORD));
|
|
}
|
|
else
|
|
{
|
|
FWriteToNet( &gwi, ( CHAR* )destBuf, dwSize );
|
|
dwSize = 0;
|
|
}
|
|
iIndex++;
|
|
iLen --;
|
|
}
|
|
if(destBuf)
|
|
free( destBuf );
|
|
}
|
|
|
|
BOOL SetOptions( LPTSTR pOption )
|
|
{
|
|
TCHAR szLoggingOn[ MAX_STRING_LENGTH ];
|
|
|
|
if( pOption == NULL )
|
|
{
|
|
Write( szSetFormat, NULL );
|
|
return FALSE;
|
|
}
|
|
|
|
RemoveLeadingNTrailingWhiteSpaces( &pOption );
|
|
|
|
if( *pOption== _T('?') )
|
|
{
|
|
Write( szSetHelp, NULL );
|
|
return FALSE;
|
|
}
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("BSASDEL") ) )
|
|
{
|
|
g_bSendBackSpaceAsDel = TRUE;
|
|
WriteMessage( IDS_BACKSPACEASDEL, ( LPTSTR )TEXT( MSG_BACKSPACEASDEL ) );
|
|
return FALSE;
|
|
}
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("CRLF") ) )
|
|
{
|
|
SetLineMode( &( gwi.trm ) );
|
|
ui.dwCrLf=TRUE;
|
|
WriteMessage( IDS_CRLF, ( LPTSTR )TEXT( MSG_CRLF ) );
|
|
return FALSE;
|
|
}
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("DELASBS") ) )
|
|
{
|
|
g_bSendDelAsBackSpace = TRUE;
|
|
WriteMessage( IDS_DELASBACKSPACE, ( LPTSTR )TEXT( MSG_DELASBACKSPACE ) );
|
|
return FALSE;
|
|
}
|
|
if( !_tcsnicmp( pOption, ( LPTSTR )TEXT("MODE"), wcslen( ( LPTSTR )TEXT("MODE") ) )
|
|
&& iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("MODE") ) ) ) )
|
|
|
|
{
|
|
TCHAR* pMode = NULL;
|
|
|
|
pOption += wcslen( ( LPTSTR )TEXT("MODE") );
|
|
pMode = _tcstok( pOption, ( LPTSTR )_T(" \t") );
|
|
|
|
if( pMode )
|
|
{
|
|
SqueezeWhiteSpace( pMode );
|
|
if( pMode[ 0 ] != L'\0' )
|
|
{
|
|
if( !_tcsicmp( pMode, ( LPTSTR )TEXT( STREAM )) )
|
|
{
|
|
if( !SetEnvironmentVariable( TEXT( SFUTLNTMODE ), TEXT( STREAM ) ) )
|
|
{
|
|
DWORD dwError = 0;
|
|
ASSERT( 0 );
|
|
dwError = GetLastError();
|
|
}
|
|
WriteMessage( IDS_STREAM, ( LPTSTR )TEXT( MSG_STREAM ) );
|
|
return FALSE;
|
|
}
|
|
else if( !_tcsicmp( pMode, ( LPTSTR )TEXT( CONSOLE ) ) )
|
|
{
|
|
if( !SetEnvironmentVariable( TEXT( SFUTLNTMODE ), TEXT( CONSOLE ) ) )
|
|
{
|
|
DWORD dwError = 0;
|
|
ASSERT( 0 );
|
|
dwError = GetLastError();
|
|
}
|
|
WriteMessage( IDS_CONSOLE, ( LPTSTR )TEXT( MSG_CONSOLE ) );
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
WriteMessage(IDS_SUPPORTED_MODES, (LPTSTR) TEXT ( MSG_SUPPORTED_MODES) );
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("NTLM") ) )
|
|
{
|
|
ui.bWillAUTH = 1;
|
|
Write( szWillAuth, NULL );
|
|
return FALSE;
|
|
}
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("LOCALECHO") ) )
|
|
{
|
|
ui.fDebug |= fdwLocalEcho;
|
|
Write( szLocalEchoOn, NULL );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !_tcsnicmp( pOption, ( LPTSTR )TEXT("LOGFILE"),
|
|
wcslen( ( LPTSTR )TEXT("LOGFILE") ) )
|
|
&& iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("LOGFILE") ) ) ) )
|
|
{
|
|
TCHAR szMsg[ MAX_STRING_LENGTH ];
|
|
TCHAR* pTerm = NULL;
|
|
|
|
pOption += wcslen( ( LPTSTR )TEXT("LOGFILE") );
|
|
pTerm = _tcstok( pOption, ( LPTSTR )_T(" \t") );
|
|
|
|
if( pTerm )
|
|
{
|
|
SqueezeWhiteSpace( pTerm );
|
|
if( !InitLogFile( pTerm ) )
|
|
{
|
|
LoadString( ghInstance, IDS_BAD_LOGFILE, szMsg, MAX_STRING_LENGTH );
|
|
Write( szMsg, NULL );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
LoadString( ghInstance, IDS_LOGFILE_NAME, szMsg, MAX_STRING_LENGTH );
|
|
Write( szMsg, pTerm, NULL );
|
|
wcsncpy( g_szLogFile, pTerm, MAX_PATH );
|
|
|
|
StartLogging( );
|
|
|
|
LoadString( ghInstance, IDS_LOGGING_ON, szLoggingOn, MAX_STRING_LENGTH );
|
|
Write( szLoggingOn, NULL );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("LOGGING") ) )
|
|
{
|
|
if( StartLogging() )
|
|
{
|
|
LoadString( ghInstance, IDS_LOGGING_ON, szLoggingOn, MAX_STRING_LENGTH );
|
|
}
|
|
else
|
|
{
|
|
LoadString( ghInstance, IDS_NO_LOGFILE, szLoggingOn, MAX_STRING_LENGTH );
|
|
}
|
|
|
|
Write( szLoggingOn, NULL );
|
|
return FALSE;
|
|
}
|
|
|
|
if( ( !_tcsnicmp( pOption, ( LPTSTR )TEXT("ESCAPE"), wcslen( ( LPTSTR )TEXT("ESCAPE") ) ) )
|
|
&& ( iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("ESCAPE") ) ) ) ||
|
|
*( pOption + wcslen( ( LPTSTR )TEXT("ESCAPE") ) ) == L'\0' ) )
|
|
{
|
|
|
|
TCHAR* pTerm = NULL;
|
|
|
|
pOption += wcslen( ( LPTSTR )TEXT("ESCAPE") );
|
|
pTerm = _tcstok( pOption, ( LPTSTR )_T(" \t") );
|
|
|
|
if( pTerm )
|
|
{
|
|
SqueezeWhiteSpace( pTerm );
|
|
if( pTerm[ 0 ] != L'\0' )
|
|
{
|
|
SetEscapeChar( pTerm[ 0 ] );
|
|
}
|
|
}
|
|
g_bIsEscapeCharValid = TRUE;
|
|
Write( g_szKbdEscape, NULL );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !_tcsnicmp( pOption, ( LPTSTR )TEXT("TERM"),
|
|
wcslen( ( LPTSTR )TEXT("TERM") ) )
|
|
&& iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("TERM") ) ) ) )
|
|
{
|
|
TCHAR* pTerm = NULL;
|
|
|
|
pOption += wcslen( ( LPTSTR )TEXT("TERM") );
|
|
pTerm = _tcstok( pOption, ( LPTSTR )_T(" \t") );
|
|
|
|
if( pTerm )
|
|
{
|
|
int iTermType;
|
|
SqueezeWhiteSpace( pTerm );
|
|
|
|
if( (iTermType = GetRequestedTermType( pTerm )) < 0 )
|
|
{
|
|
Write( szSupportedTerms, NULL );
|
|
return FALSE;
|
|
}
|
|
else
|
|
{
|
|
gwi.trm.RequestedTermType = iTermType;
|
|
}
|
|
|
|
Write( szPrefTermType, pTerm, NULL );
|
|
|
|
if (FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80))
|
|
{
|
|
ui.fDebug &= ~(fdwVT52Mode|fdwVT80Mode);
|
|
ui.fDebug &= ~(fdwKanjiModeMask);
|
|
ClearVT80(&gwi.trm);
|
|
ClearKanjiStatus(&gwi.trm, CLEAR_ALL);
|
|
ClearKanjiFlag(&gwi.trm);
|
|
SetupCharSet(&gwi.trm);
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
if((GetACP() == JAP_CODEPAGE ) && (FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) &&
|
|
!_tcsnicmp( pOption, ( LPTSTR )TEXT("CODESET"), wcslen( ( LPTSTR )TEXT("CODESET") ) )
|
|
&& iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("CODESET") ) ) ) )
|
|
{
|
|
TCHAR* pCodeset = NULL;
|
|
|
|
pOption += wcslen( ( LPTSTR )TEXT("CODESET") );
|
|
RemoveLeadingNTrailingWhiteSpaces( &pOption );
|
|
pCodeset = pOption;
|
|
|
|
if( pCodeset )
|
|
{
|
|
int i;
|
|
for(i=0 ; i<NUMBER_OF_KANJI ; ++i)
|
|
{
|
|
if(!_tcsicmp(KanjiList[i].KanjiDescription, pCodeset)) {
|
|
SetVT80(&gwi.trm);
|
|
ui.fDebug &= ~fdwKanjiModeMask;
|
|
ClearKanjiFlag(&gwi.trm);
|
|
ui.fDebug |= KanjiList[i].KanjiID;
|
|
ui.fDebug |= fdwVT80Mode;
|
|
SetKanjiMode(&gwi.trm,KanjiList[i].KanjiEmulationID);
|
|
SetupCharSet(&gwi.trm);
|
|
Write( szVT100KanjiEmulation, NULL );
|
|
Write( KanjiList[i].KanjiDescription, NULL );
|
|
Write( ( LPTSTR ) _T( "\r\n" ), NULL );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if( i >= NUMBER_OF_KANJI )
|
|
{
|
|
WriteMessage(IDS_SET_CODESET_FORMAT, (LPTSTR) TEXT ( MSG_SET_CODESET_FORMAT) );
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
Write( szSetFormat, NULL );
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
BOOL UnsetOptions( LPTSTR pOption )
|
|
{
|
|
if ( pOption == NULL )
|
|
{
|
|
Write( szUnsetFormat, NULL );
|
|
return FALSE;
|
|
}
|
|
|
|
RemoveLeadingNTrailingWhiteSpaces( &pOption );
|
|
|
|
if ( *pOption == _T('?') )
|
|
{
|
|
Write( szUnsetHelp, NULL );
|
|
return FALSE;
|
|
}
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("BSASDEL") ) )
|
|
{
|
|
g_bSendBackSpaceAsDel = FALSE;
|
|
WriteMessage( IDS_BACKSPACEASBACKSPACE, ( LPTSTR )TEXT( MSG_BACKSPACEASBACKSPACE ) );
|
|
return FALSE;
|
|
}
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("CRLF") ) )
|
|
{
|
|
ClearLineMode( &( gwi.trm ) );
|
|
ui.dwCrLf= FALSE;
|
|
WriteMessage( IDS_CR, ( LPTSTR )TEXT( MSG_CR ) );
|
|
return FALSE;
|
|
}
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("DELASBS") ) )
|
|
{
|
|
g_bSendDelAsBackSpace = FALSE;
|
|
WriteMessage( IDS_DELASDEL, ( LPTSTR )TEXT( MSG_DELASDEL ) );
|
|
return FALSE;
|
|
}
|
|
if ( !_tcsicmp( pOption, ( LPTSTR )TEXT("NTLM") ) )
|
|
{
|
|
ui.bWillAUTH = 0;
|
|
Write( szWontAuth, NULL );
|
|
return FALSE;
|
|
}
|
|
if ( !_tcsicmp( pOption, ( LPTSTR )TEXT("LOCALECHO") ) )
|
|
{
|
|
ui.fDebug &= ~fdwLocalEcho;
|
|
Write( szLocalEchoOff, NULL );
|
|
return FALSE;
|
|
}
|
|
|
|
if( !_tcsicmp( pOption, ( LPTSTR )TEXT("LOGGING") ) )
|
|
{
|
|
TCHAR szLoggingOff[ MAX_STRING_LENGTH ];
|
|
LoadString( ghInstance, IDS_LOGGING_OFF, szLoggingOff, MAX_STRING_LENGTH );
|
|
Write( szLoggingOff, NULL );
|
|
StopLogging();
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !_tcsicmp( pOption, ( LPTSTR )TEXT("ESCAPE") ) )
|
|
{
|
|
TCHAR szMsg[ MAX_STRING_LENGTH ];
|
|
|
|
g_bIsEscapeCharValid = FALSE;
|
|
LoadString( ghInstance, IDS_NO_ESCAPE , szMsg, MAX_STRING_LENGTH );
|
|
Write( szMsg, NULL );
|
|
return FALSE;
|
|
}
|
|
if ((GetACP() == JAP_CODEPAGE ) && (FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) && !_tcsicmp( pOption, ( LPTSTR )TEXT("CODESET") ) )
|
|
{
|
|
TCHAR szNoEmulation[ MAX_STRING_LENGTH ];
|
|
ui.fDebug &= ~(fdwVT52Mode|fdwVT80Mode);
|
|
ui.fDebug &= ~(fdwKanjiModeMask);
|
|
ClearVT80(&gwi.trm);
|
|
ClearKanjiStatus(&gwi.trm, CLEAR_ALL);
|
|
ClearKanjiFlag(&gwi.trm);
|
|
SetupCharSet(&gwi.trm);
|
|
LoadString( ghInstance, IDS_NO_EMULATION, szNoEmulation, MAX_STRING_LENGTH );
|
|
Write( szNoEmulation, NULL );
|
|
return FALSE;
|
|
}
|
|
Write( szUnsetFormat, NULL );
|
|
return FALSE;
|
|
}
|
|
|
|
/*#if defined(FE_IME)
|
|
BOOL EnableIMEOptions( LPTSTR pOption )
|
|
{
|
|
do {
|
|
if ( pOption == NULL )
|
|
{
|
|
Write( szEnableIMEFormat, NULL );
|
|
break;
|
|
}
|
|
|
|
if ( *pOption == _T('?') )
|
|
{
|
|
Write( szEnableIMEHelp, NULL );
|
|
break;
|
|
}
|
|
|
|
if ( !_tcsicmp( pOption, TEXT("IME") ) )
|
|
{
|
|
ui.fDebug |= fdwEnableIMESupport;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Write( szEnableIMEFormat, NULL );
|
|
break;
|
|
}
|
|
} while ( FALSE );
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL DisableIMEOptions( LPTSTR pOption )
|
|
{
|
|
do {
|
|
if ( pOption == NULL )
|
|
{
|
|
Write( szDisableIMEFormat, NULL );
|
|
break;
|
|
}
|
|
|
|
if ( *pOption == _T('?') )
|
|
{
|
|
Write( szDisableIMEHelp, NULL );
|
|
break;
|
|
}
|
|
|
|
if ( !_tcsicmp( pOption, TEXT("IME") ) )
|
|
{
|
|
ui.fDebug &= ~(fdwEnableIMESupport);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
Write( szDisableIMEFormat, NULL );
|
|
break;
|
|
}
|
|
} while ( FALSE );
|
|
|
|
return FALSE;
|
|
}
|
|
**/
|
|
//#endif /* FE_IME */
|
|
|
|
|
|
//
|
|
// (a-roopb) Added below routine to fix to bug 1007
|
|
//
|
|
LPTSTR SkipLeadingWhiteSpaces( LPTSTR szCommand )
|
|
{
|
|
int i=0;
|
|
|
|
while( szCommand[i] && _istspace( szCommand[i] ) )
|
|
{
|
|
++i;
|
|
}
|
|
|
|
return szCommand+i;
|
|
}
|
|
|
|
extern DWORD HandleTelnetSession( WI* pwi );
|
|
|
|
void ClearInitialScreen( HANDLE hConsole )
|
|
{
|
|
DWORD dwNumWritten;
|
|
COORD dwWriteCoord;
|
|
dwWriteCoord.X = 0; dwWriteCoord.Y = 0;
|
|
|
|
FillConsoleOutputCharacter( hConsole,
|
|
' ', ( gwi.sbi.dwSize.X ) * ( gwi.sbi.dwSize.Y ),
|
|
dwWriteCoord, &dwNumWritten );
|
|
FillConsoleOutputAttribute( hConsole, gwi.sbi.wAttributes,
|
|
( gwi.sbi.dwSize.X ) * ( gwi.sbi.dwSize.Y ), dwWriteCoord,
|
|
&dwNumWritten );
|
|
}
|
|
|
|
|
|
//This sets a global variable with the port number
|
|
void GetPortNumber( )
|
|
{
|
|
CHAR szPortString[ cchMaxHostName ];
|
|
struct servent *serv;
|
|
|
|
rgService = TELNET_PORT ;
|
|
|
|
if( IsCharAlpha( g_szPortNameOrNo[0] ) )
|
|
{
|
|
_snprintf( szPortString,cchMaxHostName-1, "%lS", g_szPortNameOrNo );
|
|
if((serv = getservbyname( szPortString, "tcp")) != NULL)
|
|
{
|
|
rgService = htons( (SHORT)serv->s_port );
|
|
}
|
|
else
|
|
{
|
|
rgService = 0;
|
|
}
|
|
}
|
|
else if( IsCharAlphaNumeric( g_szPortNameOrNo[0] ) )
|
|
{
|
|
rgService = _ttoi( g_szPortNameOrNo );
|
|
}
|
|
return;
|
|
}
|
|
|
|
void PrepareForNAWS( )
|
|
{
|
|
// Now we need to set the correct sizes.
|
|
// ui.dwMaxRow = gwi.sbi.dwMaximumWindowSize.Y;
|
|
//ui.dwMaxCol = gwi.sbi.dwMaximumWindowSize.X;
|
|
//This change is meant for making the client provide scrolling
|
|
ui.dwMaxRow = gwi.sbi.dwSize.Y;
|
|
ui.dwMaxCol = gwi.sbi.dwSize.X;
|
|
}
|
|
|
|
|
|
BOOL OpenTelnetSession( LPTSTR pszCommand )
|
|
{
|
|
DWORD dwWritten;
|
|
DWORD dwRead;
|
|
LPTSTR pszPort;
|
|
LPTSTR pszHost;
|
|
CHAR szHstNam[MAX_PATH + 1] = { 0 };
|
|
WCHAR szTitleName[MAX_PATH + 2 + MAX_PATH ];
|
|
TCHAR szCommand[255] = { 0 };
|
|
DWORD dwMode = ( DWORD )-1;
|
|
COORD coOrgin = { 0, 0 };
|
|
|
|
gwi.eState=Connecting;
|
|
if( pszCommand == NULL )
|
|
{
|
|
WriteConsole( gwi.hOutput, szOpenTo, _tcslen(szOpenTo), &dwWritten,
|
|
NULL );
|
|
if( ReadConsole( gwi.hInput, szCommand,
|
|
( sizeof( szCommand ) /sizeof( TCHAR) )- sizeof( TCHAR ) , &dwRead, NULL ) )
|
|
{
|
|
// no input ??
|
|
if( dwRead == 2 )
|
|
{
|
|
WriteConsole( gwi.hOutput, szOpenUsage, _tcslen(szOpenUsage),
|
|
&dwWritten, NULL );
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//error ; do something ?
|
|
return FALSE;
|
|
}
|
|
|
|
// Null Terminate the string and remove the newline characters.
|
|
szCommand[ dwRead - 1 ] = 0;
|
|
szCommand[ dwRead - 2 ] = 0;
|
|
|
|
//
|
|
// (a-roopb) Added below 5 lines to fix to bug 1007
|
|
//
|
|
pszCommand = SkipLeadingWhiteSpaces( szCommand );
|
|
if( !_tcslen(pszCommand) )
|
|
{
|
|
WriteConsole( gwi.hOutput, szOpenUsage, _tcslen(szOpenUsage), &dwWritten, NULL );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if ( fConnected )
|
|
{
|
|
CloseTelnetSession( NULL );
|
|
}
|
|
|
|
pszHost = _tcstok( pszCommand, ( LPTSTR )TEXT(" ") );
|
|
pszPort = _tcstok( NULL, ( LPTSTR )TEXT("") );
|
|
|
|
g_szPortNameOrNo[ 0 ] = 0;
|
|
if( pszPort != NULL )
|
|
{
|
|
_tcsncpy( g_szPortNameOrNo, pszPort , cchMaxHostName - 1);
|
|
}
|
|
GetPortNumber();
|
|
if(pszHost!=NULL)
|
|
{
|
|
_tcsncpy( rgchHostName, pszHost, min( _tcslen(pszHost)+1, cchMaxHostName - 1 ) );
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
rgchHostName[cchMaxHostName - 1]= _T('\0');
|
|
|
|
// need to get the current window size before creating the session.
|
|
// This is needed both for NAWS negotiation and also for creating a matching
|
|
// session buffer.
|
|
GetConsoleScreenBufferInfo( g_hTelnetPromptConsoleBuffer, &gwi.sbi );
|
|
SetWindowSize( g_hSessionConsoleBuffer );
|
|
|
|
if( FGetCodeMode( eCodeModeIMEFarEast ) )
|
|
{
|
|
if( ( gwi.sbi.srWindow.Bottom - gwi.sbi.srWindow.Top + 1 )
|
|
== gwi.sbi.dwMaximumWindowSize.Y )
|
|
{
|
|
gwi.sbi.dwSize.Y -= 1;
|
|
gwi.sbi.srWindow.Bottom -= 1;
|
|
bMaxWindow = 1;
|
|
}
|
|
}
|
|
|
|
PrepareForNAWS();
|
|
|
|
if( ui.bLogging )
|
|
{
|
|
if( !InitLoggingDataStructs() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// (a-roopb) Hack to fix bug 1092. Users may set the terminal emulation type
|
|
// before session start and DoTermReset sets the emulation types etc. to
|
|
// defaults. So we reset the emulation type after call to DoTermReset.
|
|
//
|
|
if ((FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) && ui.fDebug & fdwKanjiModeMask)
|
|
{
|
|
dwMode = ui.fDebug & fdwKanjiModeMask;
|
|
}
|
|
else
|
|
{
|
|
dwMode = ( DWORD )-1;
|
|
}
|
|
|
|
|
|
DoTermReset(&gwi, &gwi.trm);
|
|
|
|
//
|
|
// (a-roopb) Hack to fix bug 1092. Users may set the terminal emulation type
|
|
// before session start and DoTermReset sets the emulation types etc. to
|
|
// default. So we reset the emulation type again here to user chosen one.
|
|
//
|
|
if((FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) &&
|
|
!(dwMode & 0x80000000) )
|
|
{
|
|
int i;
|
|
|
|
for( i=0 ; i<NUMBER_OF_KANJI ; ++i )
|
|
{
|
|
if( dwMode == KanjiList[i].KanjiID )
|
|
{
|
|
SetVT80(&gwi.trm);
|
|
ui.fDebug &= ~fdwKanjiModeMask;
|
|
ClearKanjiFlag(&gwi.trm);
|
|
ui.fDebug |= KanjiList[i].KanjiID;
|
|
SetKanjiMode(&gwi.trm,KanjiList[i].KanjiEmulationID);
|
|
SetupCharSet(&gwi.trm);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( fPrintMessageToSessionConsole )
|
|
{
|
|
gwi.hOutput = g_hSessionConsoleBuffer;
|
|
}
|
|
|
|
WriteConsole( gwi.hOutput, szConnecting, _tcslen(szConnecting), &dwWritten, NULL);
|
|
WriteConsole( gwi.hOutput, pszHost, _tcslen(pszHost), &dwWritten, NULL);
|
|
WriteConsole( gwi.hOutput, ( LPTSTR )TEXT("..."), _tcslen( ( LPTSTR )TEXT("...")), &dwWritten, NULL);
|
|
|
|
WideCharToMultiByte( GetACP(), 0, pszHost, -1, szHstNam, MAX_PATH, NULL, NULL );
|
|
|
|
wcsncpy( szTitleName, szAppName, MAX_PATH );
|
|
szTitleName[ MAX_PATH + 1 ] = L'\0';
|
|
wcscat( szTitleName, ( LPTSTR )L" " ); // no overflow
|
|
wcsncat( szTitleName, pszHost, MAX_PATH );
|
|
szTitleName[ MAX_PATH + 1 + MAX_PATH ] = L'\0';
|
|
SetConsoleTitle( szTitleName );
|
|
|
|
fConnected = FConnectToServer(&gwi, szHstNam, &(gwi.nd));
|
|
|
|
if( fPrintMessageToSessionConsole )
|
|
{
|
|
fPrintMessageToSessionConsole = FALSE;
|
|
gwi.hOutput = g_hTelnetPromptConsoleBuffer;
|
|
}
|
|
|
|
if( fConnected == TRUE )
|
|
{
|
|
COORD dwSizeIME = gwi.sbi.dwSize;
|
|
SMALL_RECT rectIME;
|
|
|
|
if( FGetCodeMode(eCodeModeIMEFarEast) )
|
|
{
|
|
dwSizeIME.X = gwi.sbi.dwSize.X;
|
|
dwSizeIME.Y = gwi.sbi.dwSize.Y += 1;
|
|
}
|
|
|
|
if( FGetCodeMode(eCodeModeIMEFarEast) )
|
|
{
|
|
if( !SetConsoleScreenBufferSize( g_hSessionConsoleBuffer,
|
|
dwSizeIME ) )
|
|
{
|
|
fConnected = FHangupConnection(&gwi, &(gwi.nd));
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
ClearInitialScreen(g_hSessionConsoleBuffer);
|
|
|
|
memcpy( &rectIME, &gwi.sbi.srWindow, sizeof(SMALL_RECT) ); // no overflow
|
|
if( FGetCodeMode(eCodeModeIMEFarEast) )
|
|
{
|
|
rectIME.Bottom += 1;
|
|
|
|
//
|
|
// Since we are increasing the size, we need to first resize the console window
|
|
// and then the buffer otherwise it won't work
|
|
//
|
|
bWindowSizeChanged =
|
|
SetConsoleWindowInfo( g_hSessionConsoleBuffer, TRUE, &rectIME );
|
|
bBufferSizeChanged =
|
|
SetConsoleScreenBufferSize( g_hSessionConsoleBuffer, dwSizeIME );
|
|
if( bMaxWindow )
|
|
{
|
|
bWindowSizeChanged = bBufferSizeChanged = 0;
|
|
}
|
|
}
|
|
|
|
SetConsoleCursorPosition( g_hSessionConsoleBuffer, coOrgin );
|
|
srOldClientWindow = rectIME;
|
|
|
|
gwi.nd.fRespondedToWillEcho = FALSE;
|
|
gwi.nd.fRespondedToWillSGA = FALSE;
|
|
gwi.nd.fRespondedToDoAUTH = FALSE;
|
|
gwi.nd.fRespondedToDoNAWS = FALSE;
|
|
|
|
gwi.trm.dwCurChar = 0;
|
|
gwi.trm.dwCurLine = 0;
|
|
HandleTelnetSession(&gwi);
|
|
Write( ( LPTSTR )TEXT("\r\n"), NULL );
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CopyNPastePromptScreen( )
|
|
{
|
|
PCHAR_INFO pcInfo = NULL;
|
|
CONSOLE_SCREEN_BUFFER_INFO csbInfoOfPrompt;
|
|
COORD coSize = { 0, 0 };
|
|
COORD coBufferStart = { 0, 0 };
|
|
SMALL_RECT srRead = { 0, 0, 0, 0 };
|
|
SHORT wScreenSize = 0;
|
|
|
|
if( GetConsoleScreenBufferInfo( g_hTelnetPromptConsoleBuffer, &csbInfoOfPrompt ) )
|
|
{
|
|
wScreenSize = ( SHORT )( csbInfoOfPrompt.srWindow.Bottom -
|
|
csbInfoOfPrompt.srWindow.Top + 1 );
|
|
|
|
srRead.Right = ( SHORT )( csbInfoOfPrompt.dwSize.X - 1 );
|
|
coSize.X = csbInfoOfPrompt.dwSize.X;
|
|
coSize.Y = srRead.Bottom = wScreenSize;
|
|
|
|
pcInfo = ( PCHAR_INFO ) malloc( sizeof( CHAR_INFO ) *
|
|
( csbInfoOfPrompt.dwSize.X ) * ( wScreenSize ) );
|
|
|
|
if( pcInfo )
|
|
{
|
|
while( srRead.Top <= csbInfoOfPrompt.dwSize.Y - 1 )
|
|
{
|
|
if( ReadConsoleOutput( g_hTelnetPromptConsoleBuffer, pcInfo,
|
|
coSize, coBufferStart, &srRead ) )
|
|
{
|
|
WriteConsoleOutput( g_hSessionConsoleBuffer, pcInfo, coSize, coBufferStart, &srRead );
|
|
|
|
srRead.Top = ( SHORT ) ( srRead.Top + wScreenSize );
|
|
srRead.Bottom = ( SHORT ) ( srRead.Bottom + wScreenSize );
|
|
if( srRead.Bottom > csbInfoOfPrompt.dwSize.Y - 1 )
|
|
{
|
|
srRead.Bottom = ( SHORT ) ( csbInfoOfPrompt.dwSize.Y - 1 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
free( pcInfo );
|
|
|
|
SetConsoleWindowInfo( g_hSessionConsoleBuffer, TRUE,
|
|
&csbInfoOfPrompt.srWindow );
|
|
SetConsoleCursorPosition( g_hSessionConsoleBuffer,
|
|
csbInfoOfPrompt.dwCursorPosition );
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|
|
}
|
|
return( FALSE );
|
|
}
|
|
|
|
|
|
BOOL QuitTelnet(LPTSTR szCommand)
|
|
{
|
|
// Exit gracefully.
|
|
|
|
if( ui.bLogging )
|
|
{
|
|
//Close file handles if any
|
|
CloseLogging();
|
|
}
|
|
|
|
CopyNPastePromptScreen( );
|
|
|
|
CloseTelnetSession(NULL);
|
|
|
|
PostMessage(gwi.hwnd, WM_QUIT, 0, 0L);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL PrintStatus( LPTSTR szCommand )
|
|
{
|
|
TCHAR szHstNam[512];
|
|
TCHAR szTermType[81];
|
|
|
|
if ( fConnected )
|
|
{
|
|
_snwprintf( szHstNam,511, ( LPTSTR )TEXT("%S"), gwi.nd.szHostName );
|
|
Write( szConnectedTo, szHstNam, NULL );
|
|
|
|
if( gwi.trm.SentTermType != TT_UNKNOWN )
|
|
{
|
|
_snwprintf(szTermType,80, ( LPTSTR )TEXT("%S"), rgchTermType[gwi.trm.SentTermType]);
|
|
Write( szNegoTermType, szTermType, NULL );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Write( szNotConnected, NULL );
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|