Windows2003-3790/termsrv/admtools/qappsrv/qappsrv.c
2020-09-30 16:53:55 +02:00

366 lines
9.0 KiB
C

//Copyright (c) 1998 - 1999 Microsoft Corporation
/******************************************************************************
*
* QAPPSRV.C
*
* query appserver information
*
*
*******************************************************************************/
/*
* Includes
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <lm.h>
#include <winstaw.h>
#include <utilsub.h>
#include <printfoa.h>
#include <winnlsp.h>
#include "qappsrv.h"
// max length of the locale string
#define MAX_LOCALE_STRING 64
/*=============================================================================
== Global data
=============================================================================*/
WCHAR CurrentAppServer[MAXNAME];
WCHAR AppServer[MAXNAME];
WCHAR Domain[MAX_IDS_LEN+1];
USHORT help_flag = FALSE;
BOOLEAN MatchedOne = FALSE;
USHORT fAddress = FALSE;
USHORT fNoPage = FALSE;
ULONG Rows = 23;
HANDLE hConIn;
HANDLE hConOut;
TOKMAP ptm[] = {
{L" ", TMFLAG_OPTIONAL, TMFORM_STRING, MAXNAME, AppServer},
{L"/DOMAIN", TMFLAG_OPTIONAL, TMFORM_STRING, MAX_IDS_LEN, Domain},
{L"/ADDRESS", TMFLAG_OPTIONAL, TMFORM_BOOLEAN,sizeof(USHORT), &fAddress},
{L"/Continue",TMFLAG_OPTIONAL, TMFORM_BOOLEAN,sizeof(USHORT), &fNoPage },
{L"/?", TMFLAG_OPTIONAL, TMFORM_BOOLEAN,sizeof(USHORT), &help_flag},
{0, 0, 0, 0, 0}
};
/*=============================================================================
== Internal Functions Defined
=============================================================================*/
void DisplayServer( LPTSTR, LPTSTR );
void Usage( BOOLEAN bError );
int _getch( void );
/*=============================================================================
== Functions used
=============================================================================*/
int AppServerEnum( void );
void TreeTraverse( PTREETRAVERSE );
/*******************************************************************************
*
* main
*
* main routine
*
* ENTRY:
* argc (input)
* number of command line arguments
* argv (input)
* pointer to arrary of command line arguments
*
* EXIT:
* ERROR_SUCCESS - no error
*
******************************************************************************/
int __cdecl
main(INT argc, CHAR **argv)
{
CONSOLE_SCREEN_BUFFER_INFO ScreenInfo;
PSERVER_INFO_101 pCurrentServer;
ULONG Status;
ULONG rc;
WCHAR **argvW;
int i;
WCHAR wszString[MAX_LOCALE_STRING + 1];
Domain[0] = UNICODE_NULL;
setlocale(LC_ALL, ".OCP");
// We don't want LC_CTYPE set the same as the others or else we will see
// garbage output in the localized version, so we need to explicitly
// set it to correct console output code page
_snwprintf(wszString, sizeof(wszString)/sizeof(WCHAR), L".%d", GetConsoleOutputCP());
wszString[sizeof(wszString)/sizeof(WCHAR) - 1] = L'\0';
_wsetlocale(LC_CTYPE, wszString);
SetThreadUILanguage(0);
/*
* Massage the command line.
*/
argvW = MassageCommandLine((DWORD)argc);
if (argvW == NULL) {
ErrorPrintf(IDS_ERROR_MALLOC);
return(FAILURE);
}
/*
* parse the cmd line without parsing the program name (argc-1, argv+1)
*/
rc = ParseCommandLine(argc-1, argvW+1, ptm, 0);
/*
* Check for error from ParseCommandLine
*/
if ( help_flag || (rc && !(rc & PARSE_FLAG_NO_PARMS)) ) {
if ( !help_flag ) {
Usage(TRUE);
return(FAILURE);
} else {
Usage(FALSE);
return(SUCCESS);
}
}
/*
* Get handle to console
*/
hConIn = CreateFile( L"CONIN$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL );
hConOut = CreateFile( L"CONOUT$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL );
/*
* Get the number of rows on the screen
*/
if ( GetConsoleScreenBufferInfo( hConOut, &ScreenInfo ) )
Rows = ScreenInfo.dwSize.Y - 2;
/*
* Get current server
*/
Status = NetServerGetInfo( NULL, 101, (LPBYTE *) &pCurrentServer );
if ( Status ) {
ErrorPrintf(IDS_ERROR_SERVER_INFO, Status);
PutStdErr( Status, 0 );
return(FAILURE);
}
lstrcpyn( CurrentAppServer, pCurrentServer->sv101_name, MAXNAME );
/*
* Get the names and the count
*/
//if ( rc = AppServerEnum() ) {
// ErrorPrintf(IDS_ERROR_SERVER_ENUMERATE, rc );
// PutStdErr( rc, 0 );
// return(FAILURE);
//}
AppServerEnum();
/*
* Display names
*/
TreeTraverse( DisplayServer );
if (!MatchedOne)
{
if ( AppServer[0])
{
Message(IDS_ERROR_TERMSERVER_NOT_FOUND);
}
else
{
Message(IDS_ERROR_NO_TERMSERVER_IN_DOMAIN);
}
}
if( pCurrentServer != NULL )
{
NetApiBufferFree( pCurrentServer );
}
return(SUCCESS);
}
/*******************************************************************************
*
* DisplayServer
*
* This routine displays information for one server
*
*
* ENTRY:
* pName (input)
* pointer to server name
* pAddress (input)
* pointer to server address
*
* EXIT:
* nothing
*
******************************************************************************/
void
DisplayServer( LPTSTR pName, LPTSTR pAddress )
{
static ULONG RowCount = 0;
/*
* If appserver name was specified only show it
*/
if ( AppServer[0] && _wcsicmp( pName, AppServer ) )
return;
/*
* Page pause
*/
if ( !(++RowCount % Rows) && !fNoPage ) {
Message(IDS_PAUSE_MSG);
_getch();
wprintf(L"\n");
}
/*
* If first time - output title
*/
if ( !MatchedOne ) {
Message( fAddress ? IDS_TITLE_ADDR : IDS_TITLE );
Message( fAddress ? IDS_TITLE_ADDR1 : IDS_TITLE1 );
MatchedOne = TRUE;
}
if ( fAddress ) {
My_wprintf( L"%-37s%-21s\n", _wcsupr(pName), pAddress );
} else {
My_wprintf( L"%s\n", _wcsupr(pName) );
}
}
/*******************************************************************************
*
* Usage
*
* Output the usage message for this utility.
*
* ENTRY:
* bError (input)
* TRUE if the 'invalid parameter(s)' message should preceed the usage
* message and the output go to stderr; FALSE for no such error
* string and output goes to stdout.
*
* EXIT:
*
*
******************************************************************************/
void
Usage( BOOLEAN bError )
{
if ( bError ) {
ErrorPrintf(IDS_ERROR_INVALID_PARAMETERS);
ErrorPrintf(IDS_HELP_USAGE1);
ErrorPrintf(IDS_HELP_USAGE2);
ErrorPrintf(IDS_HELP_USAGE3);
ErrorPrintf(IDS_HELP_USAGE4);
ErrorPrintf(IDS_HELP_USAGE5);
ErrorPrintf(IDS_HELP_USAGE6);
ErrorPrintf(IDS_HELP_USAGE7);
} else {
Message(IDS_HELP_USAGE1);
Message(IDS_HELP_USAGE2);
Message(IDS_HELP_USAGE3);
Message(IDS_HELP_USAGE4);
Message(IDS_HELP_USAGE5);
Message(IDS_HELP_USAGE6);
Message(IDS_HELP_USAGE7);
}
}
int _getch( void )
{
INPUT_RECORD ConInpRec;
DWORD NumRead;
int ch = 0; /* single character buffer */
DWORD oldstate = 0;
/*
* Switch to raw mode (no line input, no echo input)
*/
GetConsoleMode( hConIn, &oldstate );
SetConsoleMode( hConIn, 0L );
for ( ; ; ) {
/*
* Get a console input event.
*/
if ( !ReadConsoleInput( hConIn,
&ConInpRec,
1L,
&NumRead )
|| (NumRead == 0L) )
{
ch = EOF;
break;
}
/*
* Look for, and decipher, key events.
*/
if ( (ConInpRec.EventType == KEY_EVENT) &&
ConInpRec.Event.KeyEvent.bKeyDown ) {
/*
* Easy case: if uChar.AsciiChar is non-zero, just stuff it
* into ch and quit.
*/
if ( ch = (unsigned char)ConInpRec.Event.KeyEvent.uChar.AsciiChar )
break;
}
}
/*
* Restore previous console mode.
*/
SetConsoleMode( hConIn, oldstate );
return ch;
}