Leaked source code of windows server 2003
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.

1284 lines
38 KiB

  1. //Copyright (c) 1998 - 1999 Microsoft Corporation
  2. /******************************************************************************
  3. *
  4. * QWINSTA.C
  5. *
  6. *
  7. *******************************************************************************/
  8. #include <nt.h>
  9. #include <ntrtl.h>
  10. #include <nturtl.h>
  11. #include <ntexapi.h>
  12. #include <stdio.h>
  13. #include <windows.h>
  14. #include <winstaw.h>
  15. #include <stdlib.h>
  16. #include <time.h>
  17. #include <utilsub.h>
  18. #include <process.h>
  19. #include <string.h>
  20. #include <malloc.h>
  21. #include <locale.h>
  22. #include <winnlsp.h>
  23. #include <winsock.h>
  24. #include <wsipx.h>
  25. #include <wsnwlink.h>
  26. #include <wsnetbs.h>
  27. #include <nb30.h>
  28. #include <printfoa.h>
  29. #include <allproc.h>
  30. #include "qwinsta.h"
  31. // max length of the locale string
  32. #define MAX_LOCALE_STRING 64
  33. LPCTSTR WINAPI
  34. StrConnectState( WINSTATIONSTATECLASS ConnectState,
  35. BOOL bShortString );
  36. LPCTSTR WINAPI
  37. StrAsyncConnectState( ASYNCCONNECTCLASS ConnectState );
  38. HANDLE hServerName = SERVERNAME_CURRENT;
  39. WCHAR ServerName[MAX_IDS_LEN+1];
  40. WCHAR term_string[MAX_IDS_LEN+1];
  41. USHORT a_flag = FALSE;
  42. USHORT c_flag = FALSE;
  43. USHORT f_flag = FALSE;
  44. USHORT m_flag = FALSE;
  45. USHORT help_flag = FALSE;
  46. USHORT fSm = FALSE;
  47. USHORT fDebug = FALSE;
  48. USHORT fVm = FALSE;
  49. USHORT counter_flag = FALSE;
  50. TOKMAP ptm[] = {
  51. {L" ", TMFLAG_OPTIONAL, TMFORM_S_STRING, MAX_IDS_LEN,
  52. term_string},
  53. {L"/address", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &a_flag},
  54. {L"/server", TMFLAG_OPTIONAL, TMFORM_STRING, MAX_IDS_LEN, ServerName},
  55. {L"/connect", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &c_flag},
  56. {L"/flow", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &f_flag},
  57. {L"/mode", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &m_flag},
  58. {L"/sm", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fSm},
  59. {L"/debug", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fDebug},
  60. {L"/vm", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT), &fVm},
  61. {L"/?", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT),
  62. &help_flag},
  63. {L"/counter", TMFLAG_OPTIONAL, TMFORM_BOOLEAN, sizeof(USHORT),
  64. &counter_flag},
  65. {0, 0, 0, 0, 0}
  66. };
  67. #define MAX_PRINTFOA_BUFFER_SIZE 1024
  68. char g_pWinStationName[MAX_PRINTFOA_BUFFER_SIZE];
  69. char g_pConnectState[MAX_PRINTFOA_BUFFER_SIZE];
  70. char g_pszState[MAX_PRINTFOA_BUFFER_SIZE];
  71. char g_pDeviceName[MAX_PRINTFOA_BUFFER_SIZE];
  72. char g_pWdDLL[MAX_PRINTFOA_BUFFER_SIZE];
  73. char g_pClientName[MAX_PRINTFOA_BUFFER_SIZE];
  74. char g_pClientAddress[MAX_PRINTFOA_BUFFER_SIZE];
  75. char g_pUserName[MAX_PRINTFOA_BUFFER_SIZE];
  76. WINSTATIONINFORMATION g_WinInfo;
  77. WDCONFIG g_WdInfo;
  78. WINSTATIONCONFIG g_WinConf;
  79. PDCONFIG g_PdConf;
  80. WINSTATIONCLIENT g_ClientConf;
  81. PDPARAMS g_PdParams;
  82. DEVICENAME g_DeviceName;
  83. /*
  84. * Local function prototypes
  85. */
  86. BOOLEAN PrintWinStationInfo( PLOGONID pWd, int WdCount );
  87. PWCHAR GetState( WINSTATIONSTATECLASS );
  88. void DisplayBaud( ULONG BaudRate );
  89. void DisplayParity( ULONG Parity );
  90. void DisplayDataBits( ULONG DataBits );
  91. void DisplayStopBits( ULONG StopBits );
  92. void DisplayConnect( ASYNCCONNECTCLASS ConnectFlag, USHORT header_flag );
  93. void DisplayFlow( PFLOWCONTROLCONFIG pFlow, USHORT header_flag );
  94. void DisplayLptPorts( BYTE LptMask, USHORT header_flag );
  95. void DisplayComPorts( BYTE ComMask, USHORT header_flag );
  96. void OutputHeader( void );
  97. void Usage( BOOLEAN bError );
  98. /*******************************************************************************
  99. *
  100. * main
  101. *
  102. ******************************************************************************/
  103. int __cdecl
  104. main(INT argc, CHAR **argv)
  105. {
  106. PLOGONID pWd;
  107. ULONG ByteCount, Index;
  108. UINT WdCount;
  109. ULONG Status;
  110. int rc, i;
  111. WCHAR **argvW;
  112. BOOLEAN MatchedOne = FALSE;
  113. BOOLEAN PrintWinStationInfo(PLOGONID pWd, int Count);
  114. WCHAR wszString[MAX_LOCALE_STRING + 1];
  115. TS_COUNTER TSCounters[3];
  116. setlocale(LC_ALL, ".OCP");
  117. // We don't want LC_CTYPE set the same as the others or else we will see
  118. // garbage output in the localized version, so we need to explicitly
  119. // set it to correct console output code page
  120. _snwprintf(wszString, sizeof(wszString)/sizeof(WCHAR), L".%d", GetConsoleOutputCP());
  121. wszString[sizeof(wszString)/sizeof(WCHAR) - 1] = L'\0';
  122. _wsetlocale(LC_CTYPE, wszString);
  123. SetThreadUILanguage(0);
  124. /*
  125. * Massage the command line.
  126. */
  127. argvW = MassageCommandLine((DWORD)argc);
  128. if (argvW == NULL) {
  129. ErrorPrintf(IDS_ERROR_MALLOC);
  130. return(FAILURE);
  131. }
  132. /*
  133. * parse the cmd line without parsing the program name (argc-1, argv+1)
  134. */
  135. rc = ParseCommandLine(argc-1, argvW+1, ptm, 0);
  136. /*
  137. * Check for error from ParseCommandLine
  138. */
  139. if ( help_flag || (rc && !(rc & PARSE_FLAG_NO_PARMS)) ) {
  140. if ( !help_flag ) {
  141. Usage(TRUE);
  142. return(FAILURE);
  143. } else {
  144. Usage(FALSE);
  145. return(SUCCESS);
  146. }
  147. }
  148. // If no remote server was specified, then check if we are running under Terminal Server
  149. if ((!IsTokenPresent(ptm, L"/server") ) && (!AreWeRunningTerminalServices()))
  150. {
  151. ErrorPrintf(IDS_ERROR_NOT_TS);
  152. return(FAILURE);
  153. }
  154. /*
  155. * Open the specified server
  156. */
  157. if( ServerName[0] ) {
  158. hServerName = WinStationOpenServer( ServerName );
  159. if( hServerName == NULL ) {
  160. StringErrorPrintf(IDS_ERROR_SERVER,ServerName);
  161. PutStdErr( GetLastError(), 0 );
  162. return(FAILURE);
  163. }
  164. }
  165. #if 0
  166. //
  167. // Print local WINSTATION VM info
  168. //
  169. if( fVm ) {
  170. PrintWinStationVmInfo();
  171. return( SUCCESS );
  172. }
  173. #endif
  174. /*
  175. * if no winstation was specified, display all winstations
  176. */
  177. if ( !(*term_string) )
  178. wcscpy( term_string, L"*" );
  179. /*
  180. * Allocate buffer for WinStation ids
  181. */
  182. WdCount = 10;
  183. if ( (pWd = malloc( WdCount * sizeof(LOGONID) )) == NULL ) {
  184. ErrorPrintf(IDS_ERROR_MALLOC);
  185. goto tscounters;
  186. }
  187. ByteCount = WdCount * sizeof(LOGONID);
  188. Index = 0; // Start enumeration from the begining
  189. /*
  190. * get list of active WinStations
  191. */
  192. rc = WinStationEnumerate( hServerName, &pWd, &WdCount );
  193. if ( rc ) {
  194. if ( PrintWinStationInfo(pWd, WdCount) )
  195. MatchedOne = TRUE;
  196. WinStationFreeMemory(pWd);
  197. } else {
  198. Status = GetLastError();
  199. ErrorPrintf(IDS_ERROR_WINSTATION_ENUMERATE, Status);
  200. PutStdErr( Status, 0 );
  201. goto tscounters;
  202. }
  203. /*
  204. * Check for at least one match
  205. */
  206. if ( !MatchedOne ) {
  207. StringErrorPrintf(IDS_ERROR_WINSTATION_NOT_FOUND, term_string);
  208. goto tscounters;
  209. }
  210. tscounters:
  211. if (counter_flag) {
  212. TSCounters[0].counterHead.dwCounterID = TERMSRV_TOTAL_SESSIONS;
  213. TSCounters[1].counterHead.dwCounterID = TERMSRV_DISC_SESSIONS;
  214. TSCounters[2].counterHead.dwCounterID = TERMSRV_RECON_SESSIONS;
  215. rc = WinStationGetTermSrvCountersValue(hServerName, 3, TSCounters);
  216. if (rc) {
  217. if (TSCounters[0].counterHead.bResult == TRUE) {
  218. Message(IDS_TSCOUNTER_TOTAL_SESSIONS, TSCounters[0].dwValue);
  219. }
  220. if (TSCounters[1].counterHead.bResult == TRUE) {
  221. Message(IDS_TSCOUNTER_DISC_SESSIONS, TSCounters[1].dwValue);
  222. }
  223. if (TSCounters[2].counterHead.bResult == TRUE) {
  224. Message(IDS_TSCOUNTER_RECON_SESSIONS, TSCounters[2].dwValue);
  225. }
  226. }
  227. else {
  228. ErrorPrintf(IDS_ERROR_TERMSRV_COUNTERS);
  229. }
  230. }
  231. return(SUCCESS);
  232. } /* main() */
  233. /******************************************************************************
  234. *
  235. * PrintWinStationInfo
  236. *
  237. * Printout the WinStation Information for the WinStations described in
  238. * the PLOGONID array.
  239. *
  240. * ENTRY:
  241. * pWd (input)
  242. * pointer to array of LOGONID structures.
  243. * WdCount (input)
  244. * number of elements in the pWd array.
  245. *
  246. * EXIT:
  247. * TRUE if at least one WinStation was output; FALSE if none.
  248. *
  249. *****************************************************************************/
  250. BOOLEAN
  251. PrintWinStationInfo( PLOGONID pWd,
  252. int WdCount )
  253. {
  254. int i, rc;
  255. ULONG ErrorCode;
  256. ULONG ReturnLength;
  257. PWCHAR pState;
  258. UINT MatchedOne = FALSE;
  259. static UINT HeaderFlag = FALSE;
  260. /*
  261. * Output terminal ids
  262. */
  263. for ( i=0; i < WdCount; i++ ) {
  264. if ( fSm || fDebug ) {
  265. {
  266. WideCharToMultiByte(CP_OEMCP, 0,
  267. pWd[i].WinStationName, -1,
  268. g_pWinStationName, sizeof(g_pWinStationName),
  269. NULL, NULL);
  270. WideCharToMultiByte(CP_OEMCP, 0,
  271. GetState( pWd[i].State ), -1,
  272. g_pConnectState, sizeof(g_pConnectState),
  273. NULL, NULL);
  274. fprintf( stdout, "%4u %-20s %s\n", pWd[i].LogonId, g_pWinStationName,
  275. g_pConnectState );
  276. }
  277. if ( !fDebug )
  278. continue;
  279. }
  280. if ( !WinStationObjectMatch( hServerName , &pWd[i], term_string ) )
  281. continue;
  282. /*
  283. * Get all available information so we can pick out what we need as
  284. * well as verify the API's
  285. */
  286. memset( &g_WinInfo, 0, sizeof(WINSTATIONINFORMATION) );
  287. memset( &g_WdInfo, 0, sizeof(WDCONFIG) );
  288. memset( &g_WinConf, 0, sizeof(WINSTATIONCONFIG) );
  289. memset( &g_PdConf, 0, sizeof(PDCONFIG) );
  290. memset( &g_ClientConf, 0, sizeof(WINSTATIONCLIENT) );
  291. memset( &g_PdParams, 0, sizeof(PDPARAMS) );
  292. memset( &g_DeviceName, 0, sizeof(DEVICENAME) );
  293. /*
  294. * If this WinStation is 'down', don't open and query.
  295. */
  296. if ( pWd[i].State == State_Init || pWd[i].State == State_Down || pWd[i].LogonId == -1 ) {
  297. g_WinInfo.ConnectState = pWd[i].State;
  298. } else {
  299. /*
  300. * Query WinStation's information.
  301. */
  302. rc = WinStationQueryInformation( hServerName,
  303. pWd[i].LogonId,
  304. WinStationInformation,
  305. (PVOID)&g_WinInfo,
  306. sizeof(WINSTATIONINFORMATION),
  307. &ReturnLength);
  308. if( !rc ) {
  309. continue;
  310. }
  311. if( ReturnLength != sizeof(WINSTATIONINFORMATION) ) {
  312. ErrorPrintf(IDS_ERROR_WINSTATION_INFO_VERSION_MISMATCH,
  313. L"WinStationInformation",
  314. ReturnLength, sizeof(WINSTATIONINFORMATION));
  315. continue;
  316. }
  317. rc = WinStationQueryInformation( hServerName,
  318. pWd[i].LogonId,
  319. WinStationWd,
  320. (PVOID)&g_WdInfo,
  321. sizeof(WDCONFIG),
  322. &ReturnLength);
  323. if( !rc ) {
  324. continue;
  325. }
  326. if( ReturnLength != sizeof(WDCONFIG) ) {
  327. ErrorPrintf(IDS_ERROR_WINSTATION_INFO_VERSION_MISMATCH,
  328. L"WinStationWd",
  329. ReturnLength, sizeof(WDCONFIG));
  330. continue;
  331. }
  332. rc = WinStationQueryInformation( hServerName,
  333. pWd[i].LogonId,
  334. WinStationConfiguration,
  335. (PVOID)&g_WinConf,
  336. sizeof(WINSTATIONCONFIG),
  337. &ReturnLength);
  338. if( !rc ) {
  339. continue;
  340. }
  341. if( ReturnLength != sizeof(WINSTATIONCONFIG) ) {
  342. ErrorPrintf(IDS_ERROR_WINSTATION_INFO_VERSION_MISMATCH,
  343. L"WinStationConfiguration",
  344. ReturnLength, sizeof(WINSTATIONCONFIG));
  345. continue;
  346. }
  347. rc = WinStationQueryInformation( hServerName,
  348. pWd[i].LogonId,
  349. WinStationPd,
  350. (PVOID)&g_PdConf,
  351. sizeof(PDCONFIG),
  352. &ReturnLength);
  353. if( !rc ) {
  354. continue;
  355. }
  356. if( ReturnLength != sizeof(PDCONFIG) ) {
  357. ErrorPrintf(IDS_ERROR_WINSTATION_INFO_VERSION_MISMATCH,
  358. L"WinStationPd",
  359. ReturnLength, sizeof(PDCONFIG));
  360. continue;
  361. }
  362. rc = WinStationQueryInformation( hServerName,
  363. pWd[i].LogonId,
  364. WinStationClient,
  365. (PVOID)&g_ClientConf,
  366. sizeof(WINSTATIONCLIENT),
  367. &ReturnLength);
  368. if( !rc ) {
  369. continue;
  370. }
  371. if( ReturnLength != sizeof(WINSTATIONCLIENT) ) {
  372. ErrorPrintf(IDS_ERROR_WINSTATION_INFO_VERSION_MISMATCH,
  373. L"WinStationClient",
  374. ReturnLength, sizeof(WINSTATIONCLIENT));
  375. continue;
  376. }
  377. rc = WinStationQueryInformation( hServerName,
  378. pWd[i].LogonId,
  379. WinStationPdParams,
  380. (PVOID)&g_PdParams,
  381. sizeof(PDPARAMS),
  382. &ReturnLength);
  383. if( !rc ) {
  384. continue;
  385. }
  386. if( ReturnLength != sizeof(PDPARAMS) ) {
  387. ErrorPrintf(IDS_ERROR_WINSTATION_INFO_VERSION_MISMATCH,
  388. L"WinStationPdParams",
  389. ReturnLength, sizeof(PDPARAMS));
  390. continue;
  391. }
  392. }
  393. /*
  394. * If this is a PdAsync Protocol, get the device name to display.
  395. */
  396. if ( g_PdParams.SdClass == SdAsync )
  397. wcscpy( g_DeviceName, g_PdParams.Async.DeviceName );
  398. /*
  399. * Flag sucessful match.
  400. */
  401. MatchedOne = TRUE;
  402. /*
  403. * trucate and convert to lower case
  404. */
  405. TruncateString( _wcslwr(g_WinInfo.WinStationName), 16 );
  406. TruncateString( _wcslwr(g_WdInfo.WdName), 8 );
  407. TruncateString( _wcslwr(g_DeviceName), 8 );
  408. TruncateString( _wcslwr(g_WdInfo.WdDLL), 13 );
  409. /*
  410. * Determine WinStation state
  411. */
  412. pState = GetState( g_WinInfo.ConnectState );
  413. /*
  414. * output header
  415. */
  416. if ( !HeaderFlag ) {
  417. HeaderFlag = TRUE;
  418. OutputHeader();
  419. }
  420. /*
  421. * identify current terminal
  422. */
  423. if ( (hServerName == SERVERNAME_CURRENT) && (pWd[i].LogonId == GetCurrentLogonId() ) )
  424. wprintf( L">" );
  425. else
  426. wprintf( L" " );
  427. if ( m_flag ) {
  428. {
  429. WideCharToMultiByte(CP_OEMCP, 0,
  430. g_WinInfo.WinStationName, -1,
  431. g_pWinStationName, sizeof(g_pWinStationName),
  432. NULL, NULL);
  433. WideCharToMultiByte(CP_OEMCP, 0,
  434. pState, -1,
  435. g_pszState, sizeof(g_pszState),
  436. NULL, NULL);
  437. WideCharToMultiByte(CP_OEMCP, 0,
  438. g_DeviceName, -1,
  439. g_pDeviceName, sizeof(g_pDeviceName),
  440. NULL, NULL);
  441. WideCharToMultiByte(CP_OEMCP, 0,
  442. g_WdInfo.WdDLL, -1,
  443. g_pWdDLL, sizeof(g_pWdDLL),
  444. NULL, NULL);
  445. fprintf(stdout , FORMAT_M, g_pWinStationName, g_pszState,
  446. g_pDeviceName, g_pWdDLL );
  447. }
  448. DisplayBaud( g_PdParams.Async.BaudRate );
  449. DisplayParity( g_PdParams.Async.Parity );
  450. DisplayDataBits( g_PdParams.Async.ByteSize );
  451. DisplayStopBits( g_PdParams.Async.StopBits );
  452. wprintf( L"\n" );
  453. if ( f_flag ) {
  454. DisplayFlow( &g_PdParams.Async.FlowControl, TRUE );
  455. wprintf( L"\n" );
  456. }
  457. if ( c_flag ) {
  458. DisplayConnect( g_PdParams.Async.Connect.Type, TRUE );
  459. wprintf( L"\n" );
  460. }
  461. fflush( stdout );
  462. } else if ( f_flag && c_flag ) {
  463. {
  464. WideCharToMultiByte(CP_OEMCP, 0,
  465. g_WinInfo.WinStationName, -1,
  466. g_pWinStationName, sizeof(g_pWinStationName),
  467. NULL, NULL);
  468. WideCharToMultiByte(CP_OEMCP, 0,
  469. g_DeviceName, -1,
  470. g_pDeviceName, sizeof(g_pDeviceName),
  471. NULL, NULL);
  472. fprintf(stdout,FORMAT_F_C, g_pWinStationName, g_pDeviceName );
  473. }
  474. DisplayFlow( &g_PdParams.Async.FlowControl, FALSE );
  475. DisplayConnect( g_PdParams.Async.Connect.Type, FALSE );
  476. wprintf( L"\n" );
  477. fflush( stdout );
  478. } else if ( c_flag ) {
  479. {
  480. WideCharToMultiByte(CP_OEMCP, 0,
  481. g_WinInfo.WinStationName, -1,
  482. g_pWinStationName, sizeof(g_pWinStationName),
  483. NULL, NULL);
  484. WideCharToMultiByte(CP_OEMCP, 0,
  485. pState, -1,
  486. g_pszState, sizeof(g_pszState),
  487. NULL, NULL);
  488. WideCharToMultiByte(CP_OEMCP, 0,
  489. g_DeviceName, -1,
  490. g_pDeviceName, sizeof(g_pDeviceName),
  491. NULL, NULL);
  492. WideCharToMultiByte(CP_OEMCP, 0,
  493. g_WdInfo.WdDLL, -1,
  494. g_pWdDLL, sizeof(g_pWdDLL),
  495. NULL, NULL);
  496. fprintf(stdout,FORMAT_C, g_pWinStationName, g_pszState,
  497. g_pDeviceName, g_pWdDLL );
  498. }
  499. DisplayConnect( g_PdParams.Async.Connect.Type, FALSE );
  500. wprintf( L"\n" );
  501. fflush(stdout);
  502. } else if ( f_flag ) {
  503. {
  504. WideCharToMultiByte(CP_OEMCP, 0,
  505. g_WinInfo.WinStationName, -1,
  506. g_pWinStationName, sizeof(g_pWinStationName),
  507. NULL, NULL);
  508. WideCharToMultiByte(CP_OEMCP, 0,
  509. pState, -1,
  510. g_pszState, sizeof(g_pszState),
  511. NULL, NULL);
  512. WideCharToMultiByte(CP_OEMCP, 0,
  513. g_DeviceName, -1,
  514. g_pDeviceName, sizeof(g_pDeviceName),
  515. NULL, NULL);
  516. WideCharToMultiByte(CP_OEMCP, 0,
  517. g_WdInfo.WdDLL, -1,
  518. g_pWdDLL, sizeof(g_pWdDLL),
  519. NULL, NULL);
  520. fprintf(stdout,FORMAT_F, g_pWinStationName, g_pszState,
  521. g_pDeviceName, g_pWdDLL );
  522. }
  523. DisplayFlow( &g_PdParams.Async.FlowControl, FALSE );
  524. wprintf( L"\n" );
  525. fflush(stdout);
  526. } else {
  527. {
  528. WideCharToMultiByte(CP_OEMCP, 0,
  529. g_WinInfo.WinStationName, -1,
  530. g_pWinStationName, sizeof(g_pWinStationName),
  531. NULL, NULL);
  532. WideCharToMultiByte(CP_OEMCP, 0,
  533. g_WinInfo.UserName, -1,
  534. g_pUserName, sizeof(g_pUserName),
  535. NULL, NULL);
  536. WideCharToMultiByte(CP_OEMCP, 0,
  537. pState, -1,
  538. g_pszState, sizeof(g_pszState),
  539. NULL, NULL);
  540. WideCharToMultiByte(CP_OEMCP, 0,
  541. g_DeviceName, -1,
  542. g_pDeviceName, sizeof(g_pDeviceName),
  543. NULL, NULL);
  544. WideCharToMultiByte(CP_OEMCP, 0,
  545. g_WdInfo.WdDLL, -1,
  546. g_pWdDLL, sizeof(g_pWdDLL),
  547. NULL, NULL);
  548. fprintf(stdout,FORMAT_DEFAULT, g_pWinStationName,
  549. g_pUserName, pWd[i].LogonId, g_pszState,
  550. g_pWdDLL, g_pDeviceName);
  551. }
  552. fflush(stdout);
  553. }
  554. } // end for(;;)
  555. return( MatchedOne || fSm );
  556. } /* PrintWinStationInfo() */
  557. /*******************************************************************************
  558. *
  559. * GetState
  560. *
  561. * This routine returns a pointer to a string describing the
  562. * current WinStation state.
  563. *
  564. * ENTRY:
  565. * State (input)
  566. * winstation state
  567. *
  568. * EXIT:
  569. * pointer to state string
  570. *
  571. ******************************************************************************/
  572. PWCHAR
  573. GetState( WINSTATIONSTATECLASS State )
  574. {
  575. PWCHAR pState;
  576. pState = (PWCHAR) StrConnectState(State,TRUE);
  577. /*
  578. switch ( State ) {
  579. case State_Active :
  580. pState = L"active";
  581. break;
  582. case State_Connected :
  583. pState = L"conn";
  584. break;
  585. case State_ConnectQuery :
  586. pState = L"connQ";
  587. break;
  588. case State_Shadow :
  589. pState = L"shadow";
  590. break;
  591. case State_Disconnected :
  592. pState = L"disc";
  593. break;
  594. case State_Idle :
  595. pState = L"idle";
  596. break;
  597. case State_Reset :
  598. pState = L"reset";
  599. break;
  600. case State_Down :
  601. pState = L"down";
  602. break;
  603. case State_Init :
  604. pState = L"init";
  605. break;
  606. case State_Listen :
  607. pState = L"listen";
  608. break;
  609. default :
  610. pState = L"unknown";
  611. break;
  612. }
  613. */
  614. return( pState );
  615. }
  616. /*******************************************************************************
  617. *
  618. * DisplayBaud
  619. *
  620. * This routine displays the baud rate
  621. *
  622. *
  623. * ENTRY:
  624. * BaudRate (input)
  625. * baud rate
  626. *
  627. * EXIT:
  628. * nothing
  629. *
  630. ******************************************************************************/
  631. void
  632. DisplayBaud( ULONG BaudRate )
  633. {
  634. if ( BaudRate > 0 )
  635. wprintf( L"%6lu ", BaudRate );
  636. else
  637. wprintf( L" " );
  638. fflush( stdout );
  639. } /* DisplayBaud() */
  640. /*******************************************************************************
  641. *
  642. * DisplayParity
  643. *
  644. * This routine displays parity
  645. *
  646. *
  647. * ENTRY:
  648. * Parity (input)
  649. * parity
  650. *
  651. * EXIT:
  652. * nothing
  653. *
  654. ******************************************************************************/
  655. void
  656. DisplayParity( ULONG Parity )
  657. {
  658. WCHAR szParity[64] = L"";
  659. switch ( Parity ) {
  660. case 0 :
  661. case 1 :
  662. case 2 :
  663. //
  664. // How does one handle a LoadString failure??? I choose to initialize
  665. // the storage to an empty string, and then ignore any failure.
  666. //
  667. LoadString(NULL, IDS_PARITY_NONE + Parity, szParity,
  668. sizeof(szParity) / sizeof(WCHAR));
  669. wprintf( szParity );
  670. break;
  671. default :
  672. LoadString(NULL, IDS_PARITY_BLANK, szParity,
  673. sizeof(szParity) / sizeof(WCHAR));
  674. wprintf( szParity );
  675. break;
  676. }
  677. fflush( stdout );
  678. } /* DisplayParity() */
  679. /*******************************************************************************
  680. *
  681. * DisplayDataBits
  682. *
  683. * This routine displays number of data bits
  684. *
  685. *
  686. * ENTRY:
  687. * DataBits (input)
  688. * data bits
  689. *
  690. * EXIT:
  691. * nothing
  692. *
  693. ******************************************************************************/
  694. void
  695. DisplayDataBits( ULONG DataBits )
  696. {
  697. WCHAR szDataBits[64] = L"";
  698. //
  699. // How does one handle a LoadString failure??? I choose to initialize
  700. // the storage to an empty string, and then ignore any failure. The
  701. // wprintf below, with an extra argument, won't cause any problems
  702. // if the LoadString fails.
  703. //
  704. if ( DataBits > 0 )
  705. {
  706. LoadString(NULL, IDS_DATABITS_FORMAT, szDataBits,
  707. sizeof(szDataBits) / sizeof(WCHAR));
  708. wprintf( szDataBits , DataBits );
  709. }
  710. else
  711. {
  712. LoadString(NULL, IDS_DATABITS_BLANK, szDataBits,
  713. sizeof(szDataBits) / sizeof(WCHAR));
  714. wprintf( szDataBits );
  715. }
  716. fflush( stdout );
  717. } /* DisplayDataBits() */
  718. /*******************************************************************************
  719. *
  720. * DisplayStopBits
  721. *
  722. * This routine displays the number of stop bits
  723. *
  724. *
  725. * ENTRY:
  726. * StopBits (input)
  727. * number of stop bits
  728. *
  729. * EXIT:
  730. * nothing
  731. *
  732. ******************************************************************************/
  733. void
  734. DisplayStopBits( ULONG StopBits )
  735. {
  736. WCHAR szStopBits[64] = L"";
  737. switch ( StopBits ) {
  738. case 0 :
  739. case 1 :
  740. case 2 :
  741. //
  742. // How does one handle a LoadString failure??? I choose to initialize
  743. // the storage to an empty string, and then ignore any failure.
  744. //
  745. LoadString(NULL, IDS_STOPBITS_ONE + StopBits, szStopBits,
  746. sizeof(szStopBits) / sizeof(WCHAR));
  747. wprintf( szStopBits );
  748. break;
  749. default :
  750. LoadString(NULL, IDS_STOPBITS_BLANK, szStopBits,
  751. sizeof(szStopBits) / sizeof(WCHAR));
  752. wprintf( szStopBits );
  753. break;
  754. }
  755. fflush( stdout );
  756. } /* DisplayStopBits() */
  757. /*******************************************************************************
  758. *
  759. * DisplayConnect
  760. *
  761. * This routine displays the connect settings
  762. *
  763. *
  764. * ENTRY:
  765. * ConnectFlag (input)
  766. * connect flags
  767. * header_flag (input)
  768. * TRUE to display sub-header; FALSE otherwise.
  769. *
  770. * EXIT:
  771. * nothing
  772. *
  773. ******************************************************************************/
  774. void
  775. DisplayConnect( ASYNCCONNECTCLASS ConnectFlag,
  776. USHORT header_flag )
  777. {
  778. WCHAR buffer[80] = L"";
  779. //
  780. // How does one handle a LoadString failure??? I choose to initialize
  781. // the storage to an empty string, and then ignore any failure. The
  782. // wprintf below, with an extra argument, won't cause any problems
  783. // if the LoadString fails.
  784. //
  785. if ( header_flag )
  786. {
  787. LoadString(NULL, IDS_CONNECT_HEADER, buffer, sizeof(buffer) / sizeof(WCHAR));
  788. wprintf(buffer);
  789. }
  790. buffer[0] = (WCHAR)NULL;
  791. LoadString(NULL, IDS_CONNECT_FORMAT, buffer, sizeof(buffer) / sizeof(WCHAR));
  792. wprintf( buffer, StrAsyncConnectState(ConnectFlag) );
  793. fflush( stdout );
  794. } /* DisplayConnect() */
  795. /*******************************************************************************
  796. *
  797. * DisplayFlow
  798. *
  799. * This routine displays the flow control settings
  800. *
  801. *
  802. * ENTRY:
  803. * pFlow (input)
  804. * Pointer to flow control configuration structure
  805. * header_flag (input)
  806. * TRUE to display sub-header; FALSE otherwise.
  807. *
  808. * EXIT:
  809. * nothing
  810. *
  811. ******************************************************************************/
  812. void
  813. DisplayFlow( PFLOWCONTROLCONFIG pFlow,
  814. USHORT header_flag )
  815. {
  816. WCHAR buffer[90], buf2[90], format[90];
  817. buffer[0] = 0;
  818. buf2[0] = 0;
  819. format[0] = 0;
  820. //
  821. // How does one handle a LoadString failure??? I choose to initialize
  822. // the storage to an empty string, and then ignore any failure. The
  823. // wprintf below, with an extra argument, won't cause any problems
  824. // if the LoadString fails.
  825. //
  826. if ( header_flag )
  827. {
  828. LoadString(NULL, IDS_FLOW_HEADER, buffer, sizeof(buffer) / sizeof(WCHAR));
  829. wprintf(buffer);
  830. }
  831. buffer[0] = (WCHAR)NULL;
  832. if( pFlow->fEnableDTR )
  833. {
  834. LoadString(NULL, IDS_FLOW_ENABLE_DTR, buf2, sizeof(buf2) / sizeof(WCHAR));
  835. wcscat(buffer, buf2);
  836. }
  837. buf2[0] = (WCHAR)NULL;
  838. if( pFlow->fEnableRTS )
  839. {
  840. LoadString(NULL, IDS_FLOW_ENABLE_DTR, buf2, sizeof(buf2) / sizeof(WCHAR));
  841. wcscat(buffer, buf2);
  842. }
  843. buf2[0] = (WCHAR)NULL;
  844. /*
  845. * Hardware and Software flow control are mutually exclusive
  846. */
  847. if( pFlow->Type == FlowControl_Hardware ) {
  848. if ( pFlow->HardwareReceive == ReceiveFlowControl_None )
  849. {
  850. LoadString(NULL, IDS_FLOW_RECEIVE_NONE, buf2,
  851. sizeof(buf2) / sizeof(WCHAR));
  852. }
  853. else if ( pFlow->HardwareReceive == ReceiveFlowControl_RTS )
  854. {
  855. LoadString(NULL, IDS_FLOW_RECEIVE_RTS, buf2,
  856. sizeof(buf2) / sizeof(WCHAR));
  857. }
  858. else if ( pFlow->HardwareReceive == ReceiveFlowControl_DTR )
  859. {
  860. LoadString(NULL, IDS_FLOW_RECEIVE_DTR, buf2,
  861. sizeof(buf2) / sizeof(WCHAR));
  862. }
  863. wcscat(buffer, buf2);
  864. buf2[0] = (WCHAR)NULL;
  865. if ( pFlow->HardwareTransmit == TransmitFlowControl_None )
  866. {
  867. LoadString(NULL, IDS_FLOW_TRANSMIT_NONE, buf2,
  868. sizeof(buf2) / sizeof(WCHAR));
  869. }
  870. else if ( pFlow->HardwareTransmit == TransmitFlowControl_CTS )
  871. {
  872. LoadString(NULL, IDS_FLOW_TRANSMIT_CTS, buf2,
  873. sizeof(buf2) / sizeof(WCHAR));
  874. }
  875. else if ( pFlow->HardwareTransmit == TransmitFlowControl_DSR )
  876. {
  877. LoadString(NULL, IDS_FLOW_TRANSMIT_DSR, buf2,
  878. sizeof(buf2) / sizeof(WCHAR));
  879. }
  880. wcscat(buffer, buf2);
  881. } else if ( pFlow->Type == FlowControl_Software ) {
  882. if ( pFlow->fEnableSoftwareTx )
  883. {
  884. LoadString(NULL, IDS_FLOW_SOFTWARE_TX, buf2,
  885. sizeof(buf2) / sizeof(WCHAR));
  886. }
  887. wcscat(buffer, buf2);
  888. buf2[0] = (WCHAR)NULL;
  889. if( pFlow->fEnableSoftwareRx )
  890. {
  891. LoadString(NULL, IDS_FLOW_SOFTWARE_TX, buf2,
  892. sizeof(buf2) / sizeof(WCHAR));
  893. }
  894. wcscat(buffer, buf2);
  895. buf2[0] = (WCHAR)NULL;
  896. if ( pFlow->XonChar == 0x65 && pFlow->XoffChar == 0x67 )
  897. {
  898. LoadString(NULL, IDS_FLOW_SOFTWARE_TX, buf2,
  899. sizeof(buf2) / sizeof(WCHAR));
  900. }
  901. else if( pFlow->fEnableSoftwareTx || pFlow->fEnableSoftwareRx )
  902. {
  903. LoadString(NULL, IDS_FLOW_SOFTWARE_TX, format,
  904. sizeof(format) / sizeof(WCHAR));
  905. wsprintf( buf2, format, pFlow->XonChar, pFlow->XoffChar );
  906. format[0] = (WCHAR)NULL;
  907. }
  908. wcscat( buffer, buf2 );
  909. }
  910. LoadString(NULL, IDS_FLOW_FORMAT, format, sizeof(format) / sizeof(WCHAR));
  911. wprintf( format, buffer );
  912. fflush( stdout );
  913. } /* DisplayFlow() */
  914. /*******************************************************************************
  915. *
  916. * DisplayLptPorts
  917. *
  918. * This routine displays the LPT ports that exist for a winstation
  919. *
  920. *
  921. * ENTRY:
  922. * LptMask (input)
  923. * LPT port mask
  924. * header_flag (input)
  925. * TRUE to display sub-header; FALSE otherwise.
  926. *
  927. * EXIT:
  928. * nothing
  929. *
  930. ******************************************************************************/
  931. void
  932. DisplayLptPorts( BYTE LptMask,
  933. USHORT header_flag )
  934. {
  935. WCHAR buffer[80], buf2[10], lptname[6];
  936. int i;
  937. buffer[0] = 0;
  938. buf2[0] = 0;
  939. lptname[0] = 0;
  940. //
  941. // How does one handle a LoadString failure??? I choose to initialize
  942. // the storage to an empty string, and then ignore any failure. The
  943. // wprintf below, with an extra argument, won't cause any problems
  944. // if the LoadString fails.
  945. //
  946. if ( header_flag )
  947. {
  948. LoadString(NULL, IDS_LPT_HEADER, buffer, sizeof(buffer) / sizeof(WCHAR));
  949. wprintf(buffer);
  950. }
  951. buffer[0] = (WCHAR)NULL;
  952. LoadString(NULL, IDS_LPT_FORMAT, buf2, sizeof(buf2) / sizeof(WCHAR));
  953. /*
  954. * Display from the 8 possible LPT ports.
  955. */
  956. for ( i=0; i < 8; i++ ) {
  957. if ( LptMask & (1<<i) ) {
  958. wsprintf( lptname, buf2, i+1 );
  959. wcscat( buffer, lptname );
  960. }
  961. }
  962. wprintf( buffer );
  963. fflush( stdout );
  964. } /* DisplayLptPorts() */
  965. /*******************************************************************************
  966. *
  967. * DisplayComPorts
  968. *
  969. * This routine displays the COM ports that exist for a winstation
  970. *
  971. *
  972. * ENTRY:
  973. * ComMask (input)
  974. * COM port mask
  975. * header_flag (input)
  976. * TRUE to display sub-header; FALSE otherwise.
  977. *
  978. * EXIT:
  979. * nothing
  980. *
  981. ******************************************************************************/
  982. void
  983. DisplayComPorts( BYTE ComMask,
  984. USHORT header_flag )
  985. {
  986. WCHAR buffer[80], buf2[10], comname[6];
  987. int i;
  988. buffer[0] = 0;
  989. buf2[0] = 0;
  990. comname[0] = 0;
  991. //
  992. // How does one handle a LoadString failure??? I choose to initialize
  993. // the storage to an empty string, and then ignore any failure. The
  994. // wprintf below, with an extra argument, won't cause any problems
  995. // if the LoadString fails.
  996. //
  997. if ( header_flag )
  998. {
  999. LoadString(NULL, IDS_COM_HEADER, buffer, sizeof(buffer) / sizeof(WCHAR));
  1000. wprintf(buffer);
  1001. }
  1002. buffer[0] = (WCHAR)NULL;
  1003. LoadString(NULL, IDS_COM_FORMAT, buf2, sizeof(buf2) / sizeof(WCHAR));
  1004. /*
  1005. * Display from the 8 possible LPT ports.
  1006. */
  1007. for ( i=0; i < 8; i++ ) {
  1008. if ( ComMask & (1<<i) ) {
  1009. wsprintf( comname, buf2, i+1 );
  1010. wcscat( buffer, comname );
  1011. }
  1012. }
  1013. wprintf( buffer );
  1014. fflush( stdout );
  1015. } /* DisplayComPorts() */
  1016. /*******************************************************************************
  1017. *
  1018. * OutputHeader
  1019. *
  1020. * output header
  1021. *
  1022. *
  1023. * ENTRY:
  1024. * nothing
  1025. *
  1026. * EXIT:
  1027. * nothing
  1028. *
  1029. ******************************************************************************/
  1030. void
  1031. OutputHeader( void )
  1032. {
  1033. if ( a_flag ) {
  1034. Message(IDS_HEADER_A);
  1035. } else if ( m_flag ) {
  1036. Message(IDS_HEADER_M);
  1037. } else if ( f_flag && c_flag ) {
  1038. Message(IDS_HEADER_F_C);
  1039. } else if ( c_flag ) {
  1040. Message(IDS_HEADER_C);
  1041. } else if ( f_flag ) {
  1042. Message(IDS_HEADER_F);
  1043. } else {
  1044. Message(IDS_HEADER_DEFAULT);
  1045. }
  1046. fflush(stdout);
  1047. } /* OutputHeader() */
  1048. /*******************************************************************************
  1049. *
  1050. * Usage
  1051. *
  1052. * Output the usage message for this utility.
  1053. *
  1054. * ENTRY:
  1055. * bError (input)
  1056. * TRUE if the 'invalid parameter(s)' message should preceed the usage
  1057. * message and the output go to stderr; FALSE for no such error
  1058. * string and output goes to stdout.
  1059. *
  1060. * EXIT:
  1061. *
  1062. *
  1063. ******************************************************************************/
  1064. void
  1065. Usage( BOOLEAN bError )
  1066. {
  1067. if ( bError ) {
  1068. ErrorPrintf(IDS_ERROR_INVALID_PARAMETERS);
  1069. ErrorPrintf(IDS_HELP_USAGE1);
  1070. ErrorPrintf(IDS_HELP_USAGE2);
  1071. ErrorPrintf(IDS_HELP_USAGE3);
  1072. ErrorPrintf(IDS_HELP_USAGE4);
  1073. ErrorPrintf(IDS_HELP_USAGE5);
  1074. ErrorPrintf(IDS_HELP_USAGE6);
  1075. ErrorPrintf(IDS_HELP_USAGE7);
  1076. ErrorPrintf(IDS_HELP_USAGE8);
  1077. ErrorPrintf(IDS_HELP_USAGE9);
  1078. ErrorPrintf(IDS_HELP_USAGE10);
  1079. ErrorPrintf(IDS_HELP_USAGE11);
  1080. } else {
  1081. Message(IDS_HELP_USAGE1);
  1082. Message(IDS_HELP_USAGE2);
  1083. Message(IDS_HELP_USAGE3);
  1084. Message(IDS_HELP_USAGE4);
  1085. Message(IDS_HELP_USAGE5);
  1086. Message(IDS_HELP_USAGE6);
  1087. Message(IDS_HELP_USAGE7);
  1088. Message(IDS_HELP_USAGE8);
  1089. Message(IDS_HELP_USAGE9);
  1090. Message(IDS_HELP_USAGE10);
  1091. Message(IDS_HELP_USAGE11);
  1092. }
  1093. } /* Usage() */