Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1383 lines
36 KiB

  1. /*
  2. commands.c
  3. Copyright (c) Microsoft Corporation. All rights reserved.
  4. Implementation of Telnet Commands
  5. */
  6. #pragma warning( disable: 4201 )
  7. #pragma warning( disable: 4100 )
  8. #include <windows.h> /* required for all Windows applications */
  9. #include <tchar.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <winsock2.h>
  13. #include "commands.h"
  14. #include "WinTel.h" /* specific to this program */
  15. #include "debug.h"
  16. #include "trmio.h"
  17. #include "telnet.h"
  18. extern WI gwi;
  19. extern HINSTANCE ghInstance;
  20. extern HANDLE g_hRemoteNEscapeModeDataSync;
  21. extern HANDLE g_hCaptureConsoleEvent;
  22. extern WCHAR g_szKbdEscape[];
  23. extern BOOL g_bIsEscapeCharValid;
  24. extern BOOL bDoVtNTFirstTime;
  25. extern BOOL fPrintMessageToSessionConsole;
  26. BOOL bOnlyOnce = 1;
  27. BOOL bBufferSizeChanged = 0;
  28. BOOL bWindowSizeChanged = 0;
  29. BOOL bMaxWindow = 0;
  30. extern SMALL_RECT srOldClientWindow;
  31. extern TCHAR g_szLogFile[];
  32. extern g_fSentWillNaws;
  33. void SetWindowSize( HANDLE );
  34. void GetErrMsgString( DWORD, LPTSTR* );
  35. BOOL StuffEscapeIACs( PUCHAR* ppBufDest, UCHAR bufSrc[], DWORD* pdwSize );
  36. void ConvertAndSendVTNTData( LPTSTR pData, int iLen );
  37. void *SfuZeroMemory(
  38. void *ptr,
  39. unsigned int cnt
  40. )
  41. {
  42. volatile char *vptr = (volatile char *)ptr;
  43. while (cnt)
  44. {
  45. *vptr = 0;
  46. vptr ++;
  47. cnt --;
  48. }
  49. return ptr;
  50. }
  51. BOOL PromptUser()
  52. {
  53. DWORD dwLength = 1;
  54. INPUT_RECORD irRec;
  55. ResetEvent( g_hCaptureConsoleEvent );
  56. ui.bPromptForNtlm = TRUE;
  57. irRec.EventType = FOCUS_EVENT;
  58. irRec.Event.FocusEvent.bSetFocus = TRUE;
  59. WriteConsoleInput( gwi.hInput, &irRec, dwLength, &dwLength );
  60. WaitForSingleObject( g_hCaptureConsoleEvent, INFINITE );
  61. return ui.bSendCredsToRemoteSite;
  62. }
  63. //NULL as the last arg is a MUST when you are using Write function
  64. void Write(LPTSTR lpszFmtStr, ...)
  65. {
  66. DWORD dwWritten;
  67. DWORD dwSize = 0;
  68. va_list vaArgList;
  69. TCHAR *szBuf = NULL;
  70. TCHAR *szArg = lpszFmtStr;
  71. if( !lpszFmtStr )
  72. {
  73. return;
  74. }
  75. va_start( vaArgList, lpszFmtStr );
  76. while( szArg )
  77. {
  78. dwSize += wcslen( szArg );
  79. szArg = va_arg( vaArgList, LPWSTR );
  80. }
  81. va_end( vaArgList );
  82. szBuf = ( TCHAR *) malloc( ( dwSize + 1 ) * sizeof( TCHAR ) );
  83. if( !szBuf )
  84. {
  85. return;
  86. }
  87. szBuf[dwSize] = 0;
  88. va_start( vaArgList, lpszFmtStr );
  89. //PREFIX gives "untrusted function". We want to use _vsntprintf(). Won't fix.
  90. _vsntprintf( szBuf, dwSize,lpszFmtStr, vaArgList );
  91. va_end( vaArgList );
  92. WriteConsole(gwi.hOutput, szBuf, _tcslen(szBuf), &dwWritten, NULL);
  93. free( szBuf );
  94. }
  95. void WriteMessage( DWORD dwMsgId, WCHAR szEnglishString[] )
  96. {
  97. WCHAR szMsg[ MAX_STRING_LENGTH ];
  98. if( !LoadString( ghInstance, dwMsgId, szMsg, MAX_STRING_LENGTH ) )
  99. {
  100. lstrcpyn( szMsg, szEnglishString, MAX_STRING_LENGTH - sizeof(WCHAR) );
  101. }
  102. Write( szMsg, NULL );
  103. }
  104. void FreeLoggingDataStructs()
  105. {
  106. if( g_rgciCharInfo != NULL )
  107. (void)LocalFree( (HLOCAL)g_rgciCharInfo );
  108. if (g_rgchRow != NULL)
  109. (void)LocalFree( (HLOCAL)g_rgchRow );
  110. g_rgchRow = NULL;
  111. g_rgciCharInfo = NULL;
  112. }
  113. BOOL CloseTelnetSession(LPTSTR szCommand)
  114. {
  115. CONSOLE_SCREEN_BUFFER_INFO csbInfo;
  116. if( FGetCodeMode(eCodeModeIMEFarEast) && bOnlyOnce )
  117. {
  118. bOnlyOnce = 0;
  119. GetConsoleScreenBufferInfo( g_hSessionConsoleBuffer, &csbInfo );
  120. if( bBufferSizeChanged )
  121. {
  122. csbInfo.dwSize.Y -= 1;
  123. SetConsoleScreenBufferSize( g_hSessionConsoleBuffer,
  124. csbInfo.dwSize );
  125. }
  126. if( bWindowSizeChanged )
  127. {
  128. csbInfo.srWindow.Bottom -= 1;
  129. SetConsoleWindowInfo( g_hSessionConsoleBuffer, TRUE,
  130. &csbInfo.srWindow);
  131. }
  132. }
  133. bDoVtNTFirstTime = 1;
  134. if( fConnected )
  135. {
  136. fConnected = FHangupConnection(&gwi, &(gwi.nd));
  137. }
  138. if( ui.bLogging )
  139. {
  140. FreeLoggingDataStructs();
  141. }
  142. ui.dwMaxRow = 0;
  143. ui.dwMaxCol = 0;
  144. srOldClientWindow.Left = srOldClientWindow.Right = 0;
  145. srOldClientWindow.Top = srOldClientWindow.Bottom = 0;
  146. SetEvent( g_hRemoteNEscapeModeDataSync );
  147. SetConsoleTitle( szAppName );
  148. g_fSentWillNaws = FALSE; //so that it does naws when we connect again.
  149. return FALSE;
  150. }
  151. extern CHAR* rgchTermType[];
  152. BOOL DisplayParameters(LPTSTR szCommand)
  153. {
  154. TCHAR szTermType[81];
  155. DWORD dwLen = 0;
  156. SfuZeroMemory(szTermType, sizeof(szTermType));
  157. if( g_bIsEscapeCharValid )
  158. {
  159. Write( g_szKbdEscape, NULL );
  160. }
  161. else
  162. {
  163. TCHAR szMsg[ MAX_STRING_LENGTH ];
  164. LoadString( ghInstance, IDS_NO_ESCAPE , szMsg, MAX_STRING_LENGTH );
  165. Write( szMsg, NULL );
  166. }
  167. if ( ui.bWillAUTH )
  168. Write( szWillAuth, NULL );
  169. else
  170. Write( szWontAuth, NULL );
  171. if( ui.fDebug & fdwLocalEcho )
  172. Write( szLocalEchoOn, NULL );
  173. else
  174. Write( szLocalEchoOff, NULL );
  175. if( ui.bLogging )
  176. {
  177. TCHAR szFileNameTitle[ MAX_STRING_LENGTH + 1 ];
  178. WriteMessage( IDS_LOGGING_ON, ( LPTSTR ) TEXT( MSG_LOGGING_ON ) );
  179. LoadString( ghInstance, IDS_LOGFILE_NAME, szFileNameTitle, MAX_STRING_LENGTH );
  180. Write( szFileNameTitle, g_szLogFile, NULL );
  181. }
  182. if( ui.dwCrLf )
  183. {
  184. WriteMessage( IDS_CRLF, ( LPTSTR ) _T( MSG_CRLF ) );
  185. }
  186. else
  187. {
  188. WriteMessage( IDS_CR, ( LPTSTR ) _T( MSG_CR ) );
  189. }
  190. if( g_bSendBackSpaceAsDel )
  191. {
  192. WriteMessage( IDS_BACKSPACEASDEL, ( LPTSTR ) _T( MSG_BACKSPACEASDEL ) );
  193. }
  194. if( g_bSendDelAsBackSpace )
  195. {
  196. WriteMessage( IDS_DELASBACKSPACE, ( LPTSTR ) _T( MSG_DELASBACKSPACE ) );
  197. }
  198. if( (FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) &&
  199. FIsVT80(&gwi.trm) && (gwi.trm.RequestedTermType != TT_VTNT) )
  200. {
  201. int i =0;
  202. for(i=0 ; i<NUMBER_OF_KANJI ; ++i)
  203. {
  204. if( gwi.trm.dwKanjiFlags & KanjiList[i].KanjiEmulationID )
  205. {
  206. Write( szVT100KanjiEmulation, NULL );
  207. Write( KanjiList[i].KanjiDescription, NULL );
  208. break;
  209. }
  210. }
  211. Write( TEXT("\n"), NULL );
  212. }
  213. {
  214. DWORD dwSize = 0;
  215. WCHAR wchTemp[1] = {0L};
  216. dwSize = GetEnvironmentVariable( TEXT( SFUTLNTMODE ), wchTemp, 0 );
  217. if( dwSize > 0 )
  218. {
  219. TCHAR *szMode = NULL;
  220. szMode = ( TCHAR * ) malloc( ( dwSize + 1 )* sizeof( TCHAR ) );
  221. if( szMode != NULL )
  222. {
  223. dwSize = GetEnvironmentVariable( TEXT( SFUTLNTMODE ), szMode, dwSize + 1 );
  224. if( _tcsicmp( szMode, TEXT( CONSOLE )) == 0 )
  225. {
  226. dwSize = 0; //indicating console mode
  227. }
  228. else
  229. {
  230. WriteMessage( IDS_CURRENT_MODE, ( LPTSTR )TEXT( MSG_CURRENT_MODE ) );
  231. WriteMessage( IDS_STREAM_ONLY, ( LPTSTR )TEXT( MSG_STREAM_ONLY ) );
  232. }
  233. free( szMode );
  234. }
  235. }
  236. if( dwSize == 0 )
  237. {
  238. //console mode
  239. WriteMessage( IDS_CURRENT_MODE, ( LPTSTR )TEXT( MSG_CURRENT_MODE ) );
  240. WriteMessage( IDS_CONSOLE_ONLY, ( LPTSTR )TEXT( MSG_CONSOLE_ONLY ) );
  241. }
  242. }
  243. //#if defined(FE_IME)
  244. // if( ui.fDebug & fdwEnableIMESupport )
  245. // {
  246. // Write( szEnableIMEOn, NULL );
  247. // }
  248. //#endif /* FE_IME */
  249. dwLen = sizeof(szTermType)/sizeof(WCHAR);
  250. szTermType[dwLen -1] = 0;
  251. _snwprintf( szTermType,dwLen -1, ( LPTSTR )TEXT("%S"), rgchTermType[gwi.trm.RequestedTermType] );
  252. Write( szPrefTermType, szTermType, NULL );
  253. // when we are connected we need to say what we are connected at.
  254. if ( fConnected && gwi.trm.SentTermType != TT_UNKNOWN )
  255. {
  256. _snwprintf( szTermType,(sizeof(szTermType)/sizeof(WCHAR))-1, ( LPTSTR )TEXT("%S"), rgchTermType[gwi.trm.SentTermType]);
  257. Write( szNegoTermType, szTermType, NULL );
  258. }
  259. return FALSE;
  260. }
  261. /* This initialization happens on every OpenTelnetSession()
  262. and the meemory is freed on every CloseTelnetSession() */
  263. BOOL InitLoggingDataStructs()
  264. {
  265. UINT uiSize = 0;
  266. if( g_rgchRow )
  267. {
  268. //This is needed because rows and cols may have changed
  269. FreeLoggingDataStructs();
  270. }
  271. uiSize = (UINT)(sizeof(CHAR_INFO) * ui.dwMaxCol);
  272. if( FGetCodeMode( eCodeModeFarEast ) )
  273. {
  274. uiSize *= 3; // accounting for a lot of multi byte chars
  275. }
  276. g_rgciCharInfo = (PCHAR_INFO)LocalAlloc(LPTR, uiSize );
  277. g_rgchRow = (UCHAR *)LocalAlloc(LPTR, uiSize );
  278. if ( !g_rgchRow || !g_rgciCharInfo )
  279. {
  280. ui.bLogging = FALSE;
  281. return FALSE;
  282. }
  283. return TRUE;
  284. }
  285. BOOL CloseLogging()
  286. {
  287. CloseHandle(ui.hLogFile);
  288. ui.hLogFile = NULL;
  289. return TRUE;
  290. }
  291. BOOL StopLogging()
  292. {
  293. ui.bLogging = FALSE;
  294. FreeLoggingDataStructs();
  295. return TRUE;
  296. }
  297. BOOL InitLogFile( LPTSTR szCommand )
  298. {
  299. if( ui.hLogFile )
  300. {
  301. CloseLogging( );
  302. }
  303. ui.hLogFile = CreateFile( szCommand, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL,
  304. CREATE_ALWAYS, 0, NULL);
  305. if (ui.hLogFile == INVALID_HANDLE_VALUE)
  306. {
  307. LPWSTR szErrMsg = NULL;
  308. ui.bLogging = FALSE;
  309. ui.hLogFile = NULL;
  310. GetErrMsgString( GetLastError(), &szErrMsg );
  311. Write( szErrMsg, L"\r\n", NULL );
  312. LocalFree( szErrMsg );
  313. return FALSE;
  314. }
  315. return TRUE;
  316. }
  317. BOOL StartLogging( )
  318. {
  319. ui.bLogging = FALSE;
  320. if( !ui.hLogFile ) //If we have valid logfile
  321. {
  322. return FALSE;
  323. }
  324. ui.bLogging = TRUE;
  325. if( ui.dwMaxRow != 0 && ui.dwMaxCol != 0 )
  326. {
  327. InitLoggingDataStructs();
  328. }
  329. return TRUE;
  330. }
  331. INT GetRequestedTermType( LPTSTR pszTerm )
  332. {
  333. if( !_tcsicmp( pszTerm, ( LPTSTR )TEXT("ansi") ))
  334. return 0;
  335. if( !_tcsicmp( pszTerm, ( LPTSTR )TEXT("vt100") ))
  336. return 1;
  337. if( !_tcsicmp( pszTerm, ( LPTSTR )TEXT("vt52") ))
  338. return 2;
  339. if( !_tcsicmp( pszTerm, ( LPTSTR )TEXT("vtnt") ))
  340. return 3;
  341. return -1;
  342. }
  343. void SqueezeWhiteSpace( TCHAR s[] )
  344. {
  345. INT i,j;
  346. if( s == NULL )
  347. {
  348. return;
  349. }
  350. for( i = 0, j= 0; s[i] != _T('\0'); i++ )
  351. if( !iswspace( s[i] ) )
  352. {
  353. s[j++] = s[i];
  354. }
  355. s[j] = _T('\0');
  356. }
  357. void RemoveLeadingNTrailingWhiteSpaces( LPTSTR *pOption )
  358. {
  359. DWORD dwIndex = 0;
  360. if( *pOption == NULL )
  361. {
  362. return;
  363. }
  364. dwIndex = wcslen( *pOption );
  365. if( dwIndex <= 0 )
  366. {
  367. return;
  368. }
  369. while( iswspace( (*pOption)[ dwIndex - 1 ] ) && dwIndex > 0 )
  370. {
  371. dwIndex--;
  372. }
  373. (*pOption)[ dwIndex ] = L'\0';
  374. while( iswspace( *( *pOption ) ) )
  375. {
  376. (*pOption)++;
  377. }
  378. }
  379. BOOL SendOptions( LPTSTR pOption )
  380. {
  381. if( pOption == NULL )
  382. {
  383. WriteMessage( IDS_SEND_FORMAT, ( LPTSTR )TEXT( MSG_SEND_FORMAT ) );
  384. return FALSE;
  385. }
  386. RemoveLeadingNTrailingWhiteSpaces( &pOption );
  387. if( *pOption== _T('?') )
  388. {
  389. WriteMessage( IDS_SEND_HELP, ( LPTSTR )TEXT( MSG_SEND_HELP ) );
  390. return FALSE;
  391. }
  392. if( !fConnected )
  393. {
  394. WriteMessage( IDS_NOT_CONNECTED, ( LPTSTR )TEXT( MSG_NOT_CONNECTED ) );
  395. return FALSE;
  396. }
  397. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("AO") ) )
  398. {
  399. /* Our server does nothing on receiving AO. This is for other servers */
  400. FSendTelnetCommands(gwi.hwnd, (char)AO);
  401. WriteMessage( IDS_SENT_AO, ( LPTSTR )TEXT( MSG_SENT_AO ) );
  402. return FALSE;
  403. }
  404. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("AYT") ) )
  405. {
  406. FSendTelnetCommands(gwi.hwnd, (char)AYT);
  407. WriteMessage( IDS_SENT_AYT, ( LPTSTR )TEXT( MSG_SENT_AYT ) );
  408. return FALSE;
  409. }
  410. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("ESC") ) )
  411. {
  412. if(gwi.trm.CurrentTermType == TT_VTNT)
  413. {
  414. ConvertAndSendVTNTData(&g_chEsc,1);
  415. }
  416. else
  417. {
  418. FSendChars( gwi.hwnd, &g_chEsc, sizeof( g_chEsc ) / sizeof( WCHAR ) );
  419. }
  420. WriteMessage( IDS_SENT_ESC, ( LPTSTR )TEXT( MSG_SENT_ESC ) );
  421. return FALSE;;
  422. }
  423. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("IP") ) )
  424. {
  425. FSendTelnetCommands(gwi.hwnd, (char)IP);
  426. WriteMessage( IDS_SENT_IP, ( LPTSTR )TEXT( MSG_SENT_IP ) );
  427. return FALSE;
  428. }
  429. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("SYNCH") ) )
  430. {
  431. FSendSynch( gwi.hwnd );
  432. WriteMessage( IDS_SENT_SYNCH, ( LPTSTR )TEXT( MSG_SENT_SYNCH ) );
  433. return FALSE;
  434. }
  435. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("BRK") ) )
  436. {
  437. FSendTelnetCommands(gwi.hwnd, (char)BREAK );
  438. WriteMessage( IDS_SENT_BRK, ( LPTSTR )TEXT( MSG_SENT_BRK ) );
  439. return FALSE;
  440. }
  441. //If none of the above send as it is
  442. {
  443. WCHAR szMsg[ MAX_STRING_LENGTH + 1 ];
  444. if(gwi.trm.CurrentTermType == TT_VTNT)
  445. {
  446. ConvertAndSendVTNTData(pOption,wcslen(pOption));
  447. }
  448. else
  449. {
  450. FSendChars( gwi.hwnd, pOption, wcslen( pOption ) );
  451. }
  452. if( !LoadString( ghInstance, IDS_SENT_CHARS, szMsg, MAX_STRING_LENGTH ) )
  453. {
  454. wcscpy( szMsg, TEXT( MSG_SENT_CHARS ) ); //no overflow. LoadString will return NULL terminated string.
  455. }
  456. Write( szMsg, pOption, NULL );
  457. }
  458. return FALSE;
  459. }
  460. /*++ If the data to be sent to the server is VTNT data, it cannot be sent as it is. This function
  461. will convert the given string ( pData ) into INPUT_RECORDS and send it through the socket. This
  462. is needed since the server expects VTNT data in INPUT_RECORD format and not in characters.
  463. --*/
  464. void ConvertAndSendVTNTData( LPTSTR pData, int iLen )
  465. {
  466. INPUT_RECORD sInputRecord;
  467. PUCHAR destBuf = NULL;
  468. DWORD dwSize = 0;
  469. int iIndex = 0;
  470. while(iLen)
  471. {
  472. sInputRecord.EventType = KEY_EVENT;
  473. sInputRecord.Event.KeyEvent.bKeyDown = TRUE;
  474. sInputRecord.Event.KeyEvent.uChar.UnicodeChar = pData[iIndex];
  475. dwSize = sizeof( INPUT_RECORD );
  476. if( !StuffEscapeIACs( &destBuf, (PUCHAR) &sInputRecord, &dwSize ) )
  477. {
  478. FWriteToNet(&gwi, (char *)&sInputRecord, sizeof(INPUT_RECORD));
  479. }
  480. else
  481. {
  482. FWriteToNet( &gwi, ( CHAR* )destBuf, dwSize );
  483. dwSize = 0;
  484. }
  485. iIndex++;
  486. iLen --;
  487. }
  488. if(destBuf)
  489. free( destBuf );
  490. }
  491. BOOL SetOptions( LPTSTR pOption )
  492. {
  493. TCHAR szLoggingOn[ MAX_STRING_LENGTH ];
  494. if( pOption == NULL )
  495. {
  496. Write( szSetFormat, NULL );
  497. return FALSE;
  498. }
  499. RemoveLeadingNTrailingWhiteSpaces( &pOption );
  500. if( *pOption== _T('?') )
  501. {
  502. Write( szSetHelp, NULL );
  503. return FALSE;
  504. }
  505. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("BSASDEL") ) )
  506. {
  507. g_bSendBackSpaceAsDel = TRUE;
  508. WriteMessage( IDS_BACKSPACEASDEL, ( LPTSTR )TEXT( MSG_BACKSPACEASDEL ) );
  509. return FALSE;
  510. }
  511. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("CRLF") ) )
  512. {
  513. SetLineMode( &( gwi.trm ) );
  514. ui.dwCrLf=TRUE;
  515. WriteMessage( IDS_CRLF, ( LPTSTR )TEXT( MSG_CRLF ) );
  516. return FALSE;
  517. }
  518. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("DELASBS") ) )
  519. {
  520. g_bSendDelAsBackSpace = TRUE;
  521. WriteMessage( IDS_DELASBACKSPACE, ( LPTSTR )TEXT( MSG_DELASBACKSPACE ) );
  522. return FALSE;
  523. }
  524. if( !_tcsnicmp( pOption, ( LPTSTR )TEXT("MODE"), wcslen( ( LPTSTR )TEXT("MODE") ) )
  525. && iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("MODE") ) ) ) )
  526. {
  527. TCHAR* pMode = NULL;
  528. pOption += wcslen( ( LPTSTR )TEXT("MODE") );
  529. pMode = _tcstok( pOption, ( LPTSTR )_T(" \t") );
  530. if( pMode )
  531. {
  532. SqueezeWhiteSpace( pMode );
  533. if( pMode[ 0 ] != L'\0' )
  534. {
  535. if( !_tcsicmp( pMode, ( LPTSTR )TEXT( STREAM )) )
  536. {
  537. if( !SetEnvironmentVariable( TEXT( SFUTLNTMODE ), TEXT( STREAM ) ) )
  538. {
  539. DWORD dwError = 0;
  540. ASSERT( 0 );
  541. dwError = GetLastError();
  542. }
  543. WriteMessage( IDS_STREAM, ( LPTSTR )TEXT( MSG_STREAM ) );
  544. return FALSE;
  545. }
  546. else if( !_tcsicmp( pMode, ( LPTSTR )TEXT( CONSOLE ) ) )
  547. {
  548. if( !SetEnvironmentVariable( TEXT( SFUTLNTMODE ), TEXT( CONSOLE ) ) )
  549. {
  550. DWORD dwError = 0;
  551. ASSERT( 0 );
  552. dwError = GetLastError();
  553. }
  554. WriteMessage( IDS_CONSOLE, ( LPTSTR )TEXT( MSG_CONSOLE ) );
  555. return FALSE;
  556. }
  557. else
  558. {
  559. WriteMessage(IDS_SUPPORTED_MODES, (LPTSTR) TEXT ( MSG_SUPPORTED_MODES) );
  560. return FALSE;
  561. }
  562. }
  563. }
  564. }
  565. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("NTLM") ) )
  566. {
  567. ui.bWillAUTH = 1;
  568. Write( szWillAuth, NULL );
  569. return FALSE;
  570. }
  571. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("LOCALECHO") ) )
  572. {
  573. ui.fDebug |= fdwLocalEcho;
  574. Write( szLocalEchoOn, NULL );
  575. return FALSE;
  576. }
  577. if( !_tcsnicmp( pOption, ( LPTSTR )TEXT("LOGFILE"),
  578. wcslen( ( LPTSTR )TEXT("LOGFILE") ) )
  579. && iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("LOGFILE") ) ) ) )
  580. {
  581. TCHAR szMsg[ MAX_STRING_LENGTH ];
  582. TCHAR* pTerm = NULL;
  583. pOption += wcslen( ( LPTSTR )TEXT("LOGFILE") );
  584. pTerm = _tcstok( pOption, ( LPTSTR )_T(" \t") );
  585. if( pTerm )
  586. {
  587. SqueezeWhiteSpace( pTerm );
  588. if( !InitLogFile( pTerm ) )
  589. {
  590. LoadString( ghInstance, IDS_BAD_LOGFILE, szMsg, MAX_STRING_LENGTH );
  591. Write( szMsg, NULL );
  592. return FALSE;
  593. }
  594. }
  595. LoadString( ghInstance, IDS_LOGFILE_NAME, szMsg, MAX_STRING_LENGTH );
  596. Write( szMsg, pTerm, NULL );
  597. wcsncpy( g_szLogFile, pTerm, MAX_PATH );
  598. StartLogging( );
  599. LoadString( ghInstance, IDS_LOGGING_ON, szLoggingOn, MAX_STRING_LENGTH );
  600. Write( szLoggingOn, NULL );
  601. return FALSE;
  602. }
  603. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("LOGGING") ) )
  604. {
  605. if( StartLogging() )
  606. {
  607. LoadString( ghInstance, IDS_LOGGING_ON, szLoggingOn, MAX_STRING_LENGTH );
  608. }
  609. else
  610. {
  611. LoadString( ghInstance, IDS_NO_LOGFILE, szLoggingOn, MAX_STRING_LENGTH );
  612. }
  613. Write( szLoggingOn, NULL );
  614. return FALSE;
  615. }
  616. if( ( !_tcsnicmp( pOption, ( LPTSTR )TEXT("ESCAPE"), wcslen( ( LPTSTR )TEXT("ESCAPE") ) ) )
  617. && ( iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("ESCAPE") ) ) ) ||
  618. *( pOption + wcslen( ( LPTSTR )TEXT("ESCAPE") ) ) == L'\0' ) )
  619. {
  620. TCHAR* pTerm = NULL;
  621. pOption += wcslen( ( LPTSTR )TEXT("ESCAPE") );
  622. pTerm = _tcstok( pOption, ( LPTSTR )_T(" \t") );
  623. if( pTerm )
  624. {
  625. SqueezeWhiteSpace( pTerm );
  626. if( pTerm[ 0 ] != L'\0' )
  627. {
  628. SetEscapeChar( pTerm[ 0 ] );
  629. }
  630. }
  631. g_bIsEscapeCharValid = TRUE;
  632. Write( g_szKbdEscape, NULL );
  633. return FALSE;
  634. }
  635. if( !_tcsnicmp( pOption, ( LPTSTR )TEXT("TERM"),
  636. wcslen( ( LPTSTR )TEXT("TERM") ) )
  637. && iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("TERM") ) ) ) )
  638. {
  639. TCHAR* pTerm = NULL;
  640. pOption += wcslen( ( LPTSTR )TEXT("TERM") );
  641. pTerm = _tcstok( pOption, ( LPTSTR )_T(" \t") );
  642. if( pTerm )
  643. {
  644. int iTermType;
  645. SqueezeWhiteSpace( pTerm );
  646. if( (iTermType = GetRequestedTermType( pTerm )) < 0 )
  647. {
  648. Write( szSupportedTerms, NULL );
  649. return FALSE;
  650. }
  651. else
  652. {
  653. gwi.trm.RequestedTermType = iTermType;
  654. }
  655. Write( szPrefTermType, pTerm, NULL );
  656. if (FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80))
  657. {
  658. ui.fDebug &= ~(fdwVT52Mode|fdwVT80Mode);
  659. ui.fDebug &= ~(fdwKanjiModeMask);
  660. ClearVT80(&gwi.trm);
  661. ClearKanjiStatus(&gwi.trm, CLEAR_ALL);
  662. ClearKanjiFlag(&gwi.trm);
  663. SetupCharSet(&gwi.trm);
  664. }
  665. }
  666. return FALSE;
  667. }
  668. if((GetACP() == JAP_CODEPAGE ) && (FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) &&
  669. !_tcsnicmp( pOption, ( LPTSTR )TEXT("CODESET"), wcslen( ( LPTSTR )TEXT("CODESET") ) )
  670. && iswspace( *( pOption + wcslen( ( LPTSTR )TEXT("CODESET") ) ) ) )
  671. {
  672. TCHAR* pCodeset = NULL;
  673. pOption += wcslen( ( LPTSTR )TEXT("CODESET") );
  674. RemoveLeadingNTrailingWhiteSpaces( &pOption );
  675. pCodeset = pOption;
  676. if( pCodeset )
  677. {
  678. int i;
  679. for(i=0 ; i<NUMBER_OF_KANJI ; ++i)
  680. {
  681. if(!_tcsicmp(KanjiList[i].KanjiDescription, pCodeset)) {
  682. SetVT80(&gwi.trm);
  683. ui.fDebug &= ~fdwKanjiModeMask;
  684. ClearKanjiFlag(&gwi.trm);
  685. ui.fDebug |= KanjiList[i].KanjiID;
  686. ui.fDebug |= fdwVT80Mode;
  687. SetKanjiMode(&gwi.trm,KanjiList[i].KanjiEmulationID);
  688. SetupCharSet(&gwi.trm);
  689. Write( szVT100KanjiEmulation, NULL );
  690. Write( KanjiList[i].KanjiDescription, NULL );
  691. Write( ( LPTSTR ) _T( "\r\n" ), NULL );
  692. return FALSE;
  693. }
  694. }
  695. if( i >= NUMBER_OF_KANJI )
  696. {
  697. WriteMessage(IDS_SET_CODESET_FORMAT, (LPTSTR) TEXT ( MSG_SET_CODESET_FORMAT) );
  698. }
  699. }
  700. return FALSE;
  701. }
  702. Write( szSetFormat, NULL );
  703. return FALSE;
  704. }
  705. BOOL UnsetOptions( LPTSTR pOption )
  706. {
  707. if ( pOption == NULL )
  708. {
  709. Write( szUnsetFormat, NULL );
  710. return FALSE;
  711. }
  712. RemoveLeadingNTrailingWhiteSpaces( &pOption );
  713. if ( *pOption == _T('?') )
  714. {
  715. Write( szUnsetHelp, NULL );
  716. return FALSE;
  717. }
  718. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("BSASDEL") ) )
  719. {
  720. g_bSendBackSpaceAsDel = FALSE;
  721. WriteMessage( IDS_BACKSPACEASBACKSPACE, ( LPTSTR )TEXT( MSG_BACKSPACEASBACKSPACE ) );
  722. return FALSE;
  723. }
  724. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("CRLF") ) )
  725. {
  726. ClearLineMode( &( gwi.trm ) );
  727. ui.dwCrLf= FALSE;
  728. WriteMessage( IDS_CR, ( LPTSTR )TEXT( MSG_CR ) );
  729. return FALSE;
  730. }
  731. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("DELASBS") ) )
  732. {
  733. g_bSendDelAsBackSpace = FALSE;
  734. WriteMessage( IDS_DELASDEL, ( LPTSTR )TEXT( MSG_DELASDEL ) );
  735. return FALSE;
  736. }
  737. if ( !_tcsicmp( pOption, ( LPTSTR )TEXT("NTLM") ) )
  738. {
  739. ui.bWillAUTH = 0;
  740. Write( szWontAuth, NULL );
  741. return FALSE;
  742. }
  743. if ( !_tcsicmp( pOption, ( LPTSTR )TEXT("LOCALECHO") ) )
  744. {
  745. ui.fDebug &= ~fdwLocalEcho;
  746. Write( szLocalEchoOff, NULL );
  747. return FALSE;
  748. }
  749. if( !_tcsicmp( pOption, ( LPTSTR )TEXT("LOGGING") ) )
  750. {
  751. TCHAR szLoggingOff[ MAX_STRING_LENGTH ];
  752. LoadString( ghInstance, IDS_LOGGING_OFF, szLoggingOff, MAX_STRING_LENGTH );
  753. Write( szLoggingOff, NULL );
  754. StopLogging();
  755. return FALSE;
  756. }
  757. if ( !_tcsicmp( pOption, ( LPTSTR )TEXT("ESCAPE") ) )
  758. {
  759. TCHAR szMsg[ MAX_STRING_LENGTH ];
  760. g_bIsEscapeCharValid = FALSE;
  761. LoadString( ghInstance, IDS_NO_ESCAPE , szMsg, MAX_STRING_LENGTH );
  762. Write( szMsg, NULL );
  763. return FALSE;
  764. }
  765. if ((GetACP() == JAP_CODEPAGE ) && (FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) && !_tcsicmp( pOption, ( LPTSTR )TEXT("CODESET") ) )
  766. {
  767. TCHAR szNoEmulation[ MAX_STRING_LENGTH ];
  768. ui.fDebug &= ~(fdwVT52Mode|fdwVT80Mode);
  769. ui.fDebug &= ~(fdwKanjiModeMask);
  770. ClearVT80(&gwi.trm);
  771. ClearKanjiStatus(&gwi.trm, CLEAR_ALL);
  772. ClearKanjiFlag(&gwi.trm);
  773. SetupCharSet(&gwi.trm);
  774. LoadString( ghInstance, IDS_NO_EMULATION, szNoEmulation, MAX_STRING_LENGTH );
  775. Write( szNoEmulation, NULL );
  776. return FALSE;
  777. }
  778. Write( szUnsetFormat, NULL );
  779. return FALSE;
  780. }
  781. /*#if defined(FE_IME)
  782. BOOL EnableIMEOptions( LPTSTR pOption )
  783. {
  784. do {
  785. if ( pOption == NULL )
  786. {
  787. Write( szEnableIMEFormat, NULL );
  788. break;
  789. }
  790. if ( *pOption == _T('?') )
  791. {
  792. Write( szEnableIMEHelp, NULL );
  793. break;
  794. }
  795. if ( !_tcsicmp( pOption, TEXT("IME") ) )
  796. {
  797. ui.fDebug |= fdwEnableIMESupport;
  798. break;
  799. }
  800. else
  801. {
  802. Write( szEnableIMEFormat, NULL );
  803. break;
  804. }
  805. } while ( FALSE );
  806. return FALSE;
  807. }
  808. BOOL DisableIMEOptions( LPTSTR pOption )
  809. {
  810. do {
  811. if ( pOption == NULL )
  812. {
  813. Write( szDisableIMEFormat, NULL );
  814. break;
  815. }
  816. if ( *pOption == _T('?') )
  817. {
  818. Write( szDisableIMEHelp, NULL );
  819. break;
  820. }
  821. if ( !_tcsicmp( pOption, TEXT("IME") ) )
  822. {
  823. ui.fDebug &= ~(fdwEnableIMESupport);
  824. break;
  825. }
  826. else
  827. {
  828. Write( szDisableIMEFormat, NULL );
  829. break;
  830. }
  831. } while ( FALSE );
  832. return FALSE;
  833. }
  834. **/
  835. //#endif /* FE_IME */
  836. //
  837. // (a-roopb) Added below routine to fix to bug 1007
  838. //
  839. LPTSTR SkipLeadingWhiteSpaces( LPTSTR szCommand )
  840. {
  841. int i=0;
  842. while( szCommand[i] && _istspace( szCommand[i] ) )
  843. {
  844. ++i;
  845. }
  846. return szCommand+i;
  847. }
  848. extern DWORD HandleTelnetSession( WI* pwi );
  849. void ClearInitialScreen( HANDLE hConsole )
  850. {
  851. DWORD dwNumWritten;
  852. COORD dwWriteCoord;
  853. dwWriteCoord.X = 0; dwWriteCoord.Y = 0;
  854. FillConsoleOutputCharacter( hConsole,
  855. ' ', ( gwi.sbi.dwSize.X ) * ( gwi.sbi.dwSize.Y ),
  856. dwWriteCoord, &dwNumWritten );
  857. FillConsoleOutputAttribute( hConsole, gwi.sbi.wAttributes,
  858. ( gwi.sbi.dwSize.X ) * ( gwi.sbi.dwSize.Y ), dwWriteCoord,
  859. &dwNumWritten );
  860. }
  861. //This sets a global variable with the port number
  862. void GetPortNumber( )
  863. {
  864. CHAR szPortString[ cchMaxHostName ];
  865. struct servent *serv;
  866. rgService = TELNET_PORT ;
  867. if( IsCharAlpha( g_szPortNameOrNo[0] ) )
  868. {
  869. _snprintf( szPortString,cchMaxHostName-1, "%lS", g_szPortNameOrNo );
  870. if((serv = getservbyname( szPortString, "tcp")) != NULL)
  871. {
  872. rgService = htons( (SHORT)serv->s_port );
  873. }
  874. else
  875. {
  876. rgService = 0;
  877. }
  878. }
  879. else if( IsCharAlphaNumeric( g_szPortNameOrNo[0] ) )
  880. {
  881. rgService = _ttoi( g_szPortNameOrNo );
  882. }
  883. return;
  884. }
  885. void PrepareForNAWS( )
  886. {
  887. // Now we need to set the correct sizes.
  888. // ui.dwMaxRow = gwi.sbi.dwMaximumWindowSize.Y;
  889. //ui.dwMaxCol = gwi.sbi.dwMaximumWindowSize.X;
  890. //This change is meant for making the client provide scrolling
  891. ui.dwMaxRow = gwi.sbi.dwSize.Y;
  892. ui.dwMaxCol = gwi.sbi.dwSize.X;
  893. }
  894. BOOL OpenTelnetSession( LPTSTR pszCommand )
  895. {
  896. DWORD dwWritten;
  897. DWORD dwRead;
  898. LPTSTR pszPort;
  899. LPTSTR pszHost;
  900. CHAR szHstNam[MAX_PATH + 1] = { 0 };
  901. WCHAR szTitleName[MAX_PATH + 2 + MAX_PATH ];
  902. TCHAR szCommand[255] = { 0 };
  903. DWORD dwMode = ( DWORD )-1;
  904. COORD coOrgin = { 0, 0 };
  905. gwi.eState=Connecting;
  906. if( pszCommand == NULL )
  907. {
  908. WriteConsole( gwi.hOutput, szOpenTo, _tcslen(szOpenTo), &dwWritten,
  909. NULL );
  910. if( ReadConsole( gwi.hInput, szCommand,
  911. ( sizeof( szCommand ) /sizeof( TCHAR) )- sizeof( TCHAR ) , &dwRead, NULL ) )
  912. {
  913. // no input ??
  914. if( dwRead == 2 )
  915. {
  916. WriteConsole( gwi.hOutput, szOpenUsage, _tcslen(szOpenUsage),
  917. &dwWritten, NULL );
  918. return FALSE;
  919. }
  920. }
  921. else
  922. {
  923. //error ; do something ?
  924. return FALSE;
  925. }
  926. // Null Terminate the string and remove the newline characters.
  927. szCommand[ dwRead - 1 ] = 0;
  928. szCommand[ dwRead - 2 ] = 0;
  929. //
  930. // (a-roopb) Added below 5 lines to fix to bug 1007
  931. //
  932. pszCommand = SkipLeadingWhiteSpaces( szCommand );
  933. if( !_tcslen(pszCommand) )
  934. {
  935. WriteConsole( gwi.hOutput, szOpenUsage, _tcslen(szOpenUsage), &dwWritten, NULL );
  936. return FALSE;
  937. }
  938. }
  939. if ( fConnected )
  940. {
  941. CloseTelnetSession( NULL );
  942. }
  943. pszHost = _tcstok( pszCommand, ( LPTSTR )TEXT(" ") );
  944. pszPort = _tcstok( NULL, ( LPTSTR )TEXT("") );
  945. g_szPortNameOrNo[ 0 ] = 0;
  946. if( pszPort != NULL )
  947. {
  948. _tcsncpy( g_szPortNameOrNo, pszPort , cchMaxHostName - 1);
  949. }
  950. GetPortNumber();
  951. if(pszHost!=NULL)
  952. {
  953. _tcsncpy( rgchHostName, pszHost, min( _tcslen(pszHost)+1, cchMaxHostName - 1 ) );
  954. }
  955. else
  956. {
  957. return FALSE;
  958. }
  959. rgchHostName[cchMaxHostName - 1]= _T('\0');
  960. // need to get the current window size before creating the session.
  961. // This is needed both for NAWS negotiation and also for creating a matching
  962. // session buffer.
  963. GetConsoleScreenBufferInfo( g_hTelnetPromptConsoleBuffer, &gwi.sbi );
  964. SetWindowSize( g_hSessionConsoleBuffer );
  965. if( FGetCodeMode( eCodeModeIMEFarEast ) )
  966. {
  967. if( ( gwi.sbi.srWindow.Bottom - gwi.sbi.srWindow.Top + 1 )
  968. == gwi.sbi.dwMaximumWindowSize.Y )
  969. {
  970. gwi.sbi.dwSize.Y -= 1;
  971. gwi.sbi.srWindow.Bottom -= 1;
  972. bMaxWindow = 1;
  973. }
  974. }
  975. PrepareForNAWS();
  976. if( ui.bLogging )
  977. {
  978. if( !InitLoggingDataStructs() )
  979. {
  980. return FALSE;
  981. }
  982. }
  983. //
  984. // (a-roopb) Hack to fix bug 1092. Users may set the terminal emulation type
  985. // before session start and DoTermReset sets the emulation types etc. to
  986. // defaults. So we reset the emulation type after call to DoTermReset.
  987. //
  988. if ((FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) && ui.fDebug & fdwKanjiModeMask)
  989. {
  990. dwMode = ui.fDebug & fdwKanjiModeMask;
  991. }
  992. else
  993. {
  994. dwMode = ( DWORD )-1;
  995. }
  996. DoTermReset(&gwi, &gwi.trm);
  997. //
  998. // (a-roopb) Hack to fix bug 1092. Users may set the terminal emulation type
  999. // before session start and DoTermReset sets the emulation types etc. to
  1000. // default. So we reset the emulation type again here to user chosen one.
  1001. //
  1002. if((FGetCodeMode(eCodeModeFarEast) && FGetCodeMode(eCodeModeVT80)) &&
  1003. !(dwMode & 0x80000000) )
  1004. {
  1005. int i;
  1006. for( i=0 ; i<NUMBER_OF_KANJI ; ++i )
  1007. {
  1008. if( dwMode == KanjiList[i].KanjiID )
  1009. {
  1010. SetVT80(&gwi.trm);
  1011. ui.fDebug &= ~fdwKanjiModeMask;
  1012. ClearKanjiFlag(&gwi.trm);
  1013. ui.fDebug |= KanjiList[i].KanjiID;
  1014. SetKanjiMode(&gwi.trm,KanjiList[i].KanjiEmulationID);
  1015. SetupCharSet(&gwi.trm);
  1016. break;
  1017. }
  1018. }
  1019. }
  1020. if( fPrintMessageToSessionConsole )
  1021. {
  1022. gwi.hOutput = g_hSessionConsoleBuffer;
  1023. }
  1024. WriteConsole( gwi.hOutput, szConnecting, _tcslen(szConnecting), &dwWritten, NULL);
  1025. WriteConsole( gwi.hOutput, pszHost, _tcslen(pszHost), &dwWritten, NULL);
  1026. WriteConsole( gwi.hOutput, ( LPTSTR )TEXT("..."), _tcslen( ( LPTSTR )TEXT("...")), &dwWritten, NULL);
  1027. WideCharToMultiByte( GetACP(), 0, pszHost, -1, szHstNam, MAX_PATH, NULL, NULL );
  1028. wcsncpy( szTitleName, szAppName, MAX_PATH );
  1029. szTitleName[ MAX_PATH + 1 ] = L'\0';
  1030. wcscat( szTitleName, ( LPTSTR )L" " ); // no overflow
  1031. wcsncat( szTitleName, pszHost, MAX_PATH );
  1032. szTitleName[ MAX_PATH + 1 + MAX_PATH ] = L'\0';
  1033. SetConsoleTitle( szTitleName );
  1034. fConnected = FConnectToServer(&gwi, szHstNam, &(gwi.nd));
  1035. if( fPrintMessageToSessionConsole )
  1036. {
  1037. fPrintMessageToSessionConsole = FALSE;
  1038. gwi.hOutput = g_hTelnetPromptConsoleBuffer;
  1039. }
  1040. if( fConnected == TRUE )
  1041. {
  1042. COORD dwSizeIME = gwi.sbi.dwSize;
  1043. SMALL_RECT rectIME;
  1044. if( FGetCodeMode(eCodeModeIMEFarEast) )
  1045. {
  1046. dwSizeIME.X = gwi.sbi.dwSize.X;
  1047. dwSizeIME.Y = gwi.sbi.dwSize.Y += 1;
  1048. }
  1049. if( FGetCodeMode(eCodeModeIMEFarEast) )
  1050. {
  1051. if( !SetConsoleScreenBufferSize( g_hSessionConsoleBuffer,
  1052. dwSizeIME ) )
  1053. {
  1054. fConnected = FHangupConnection(&gwi, &(gwi.nd));
  1055. return FALSE;
  1056. }
  1057. }
  1058. ClearInitialScreen(g_hSessionConsoleBuffer);
  1059. memcpy( &rectIME, &gwi.sbi.srWindow, sizeof(SMALL_RECT) ); // no overflow
  1060. if( FGetCodeMode(eCodeModeIMEFarEast) )
  1061. {
  1062. rectIME.Bottom += 1;
  1063. //
  1064. // Since we are increasing the size, we need to first resize the console window
  1065. // and then the buffer otherwise it won't work
  1066. //
  1067. bWindowSizeChanged =
  1068. SetConsoleWindowInfo( g_hSessionConsoleBuffer, TRUE, &rectIME );
  1069. bBufferSizeChanged =
  1070. SetConsoleScreenBufferSize( g_hSessionConsoleBuffer, dwSizeIME );
  1071. if( bMaxWindow )
  1072. {
  1073. bWindowSizeChanged = bBufferSizeChanged = 0;
  1074. }
  1075. }
  1076. SetConsoleCursorPosition( g_hSessionConsoleBuffer, coOrgin );
  1077. srOldClientWindow = rectIME;
  1078. gwi.nd.fRespondedToWillEcho = FALSE;
  1079. gwi.nd.fRespondedToWillSGA = FALSE;
  1080. gwi.nd.fRespondedToDoAUTH = FALSE;
  1081. gwi.nd.fRespondedToDoNAWS = FALSE;
  1082. gwi.trm.dwCurChar = 0;
  1083. gwi.trm.dwCurLine = 0;
  1084. HandleTelnetSession(&gwi);
  1085. Write( ( LPTSTR )TEXT("\r\n"), NULL );
  1086. }
  1087. return FALSE;
  1088. }
  1089. BOOL CopyNPastePromptScreen( )
  1090. {
  1091. PCHAR_INFO pcInfo = NULL;
  1092. CONSOLE_SCREEN_BUFFER_INFO csbInfoOfPrompt;
  1093. COORD coSize = { 0, 0 };
  1094. COORD coBufferStart = { 0, 0 };
  1095. SMALL_RECT srRead = { 0, 0, 0, 0 };
  1096. SHORT wScreenSize = 0;
  1097. if( GetConsoleScreenBufferInfo( g_hTelnetPromptConsoleBuffer, &csbInfoOfPrompt ) )
  1098. {
  1099. wScreenSize = ( SHORT )( csbInfoOfPrompt.srWindow.Bottom -
  1100. csbInfoOfPrompt.srWindow.Top + 1 );
  1101. srRead.Right = ( SHORT )( csbInfoOfPrompt.dwSize.X - 1 );
  1102. coSize.X = csbInfoOfPrompt.dwSize.X;
  1103. coSize.Y = srRead.Bottom = wScreenSize;
  1104. pcInfo = ( PCHAR_INFO ) malloc( sizeof( CHAR_INFO ) *
  1105. ( csbInfoOfPrompt.dwSize.X ) * ( wScreenSize ) );
  1106. if( pcInfo )
  1107. {
  1108. while( srRead.Top <= csbInfoOfPrompt.dwSize.Y - 1 )
  1109. {
  1110. if( ReadConsoleOutput( g_hTelnetPromptConsoleBuffer, pcInfo,
  1111. coSize, coBufferStart, &srRead ) )
  1112. {
  1113. WriteConsoleOutput( g_hSessionConsoleBuffer, pcInfo, coSize, coBufferStart, &srRead );
  1114. srRead.Top = ( SHORT ) ( srRead.Top + wScreenSize );
  1115. srRead.Bottom = ( SHORT ) ( srRead.Bottom + wScreenSize );
  1116. if( srRead.Bottom > csbInfoOfPrompt.dwSize.Y - 1 )
  1117. {
  1118. srRead.Bottom = ( SHORT ) ( csbInfoOfPrompt.dwSize.Y - 1 );
  1119. }
  1120. }
  1121. else
  1122. {
  1123. break;
  1124. }
  1125. }
  1126. free( pcInfo );
  1127. SetConsoleWindowInfo( g_hSessionConsoleBuffer, TRUE,
  1128. &csbInfoOfPrompt.srWindow );
  1129. SetConsoleCursorPosition( g_hSessionConsoleBuffer,
  1130. csbInfoOfPrompt.dwCursorPosition );
  1131. return( TRUE );
  1132. }
  1133. }
  1134. return( FALSE );
  1135. }
  1136. BOOL QuitTelnet(LPTSTR szCommand)
  1137. {
  1138. // Exit gracefully.
  1139. if( ui.bLogging )
  1140. {
  1141. //Close file handles if any
  1142. CloseLogging();
  1143. }
  1144. CopyNPastePromptScreen( );
  1145. CloseTelnetSession(NULL);
  1146. PostMessage(gwi.hwnd, WM_QUIT, 0, 0L);
  1147. return TRUE;
  1148. }
  1149. BOOL PrintStatus( LPTSTR szCommand )
  1150. {
  1151. TCHAR szHstNam[512];
  1152. TCHAR szTermType[81];
  1153. if ( fConnected )
  1154. {
  1155. _snwprintf( szHstNam,511, ( LPTSTR )TEXT("%S"), gwi.nd.szHostName );
  1156. Write( szConnectedTo, szHstNam, NULL );
  1157. if( gwi.trm.SentTermType != TT_UNKNOWN )
  1158. {
  1159. _snwprintf(szTermType,80, ( LPTSTR )TEXT("%S"), rgchTermType[gwi.trm.SentTermType]);
  1160. Write( szNegoTermType, szTermType, NULL );
  1161. }
  1162. }
  1163. else
  1164. {
  1165. Write( szNotConnected, NULL );
  1166. }
  1167. return FALSE;
  1168. }