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.
 
 
 
 
 
 

644 lines
19 KiB

/*********************************************************************************************
Copyright (c) Microsoft Corporation
Module Name:
GpResult.cpp
Abstract:
This file contains the main entry point function for this tool and also the
function to parse the command line arguments.
Author:
Wipro Technologies
Revision History:
20-Feb-2001 : Created It.
*********************************************************************************************/
#include "pch.h"
#include "GpResult.h"
#include "wmi.h"
/*********************************************************************************************
Routine Description:
This is main entry point for this utility. Different function calls are made from here,
depending on the command line parameters passed to this utility.
Arguments:
[in] argc : Number of Command line arguments.
[in] argv : Pointer to Command line arguments.
Return Value:
Zero on success
Corresponding error code on failure.
*********************************************************************************************/
DWORD _cdecl _tmain( DWORD argc, LPCWSTR argv[] )
{
// local variables
CGpResult GpResult;
BOOL bResult = FALSE;
BOOL bNeedUsageMsg = FALSE;
// initialize the GpResult utility
if( GpResult.Initialize() == FALSE )
{
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
EXIT_PROCESS( ERROR_EXIT );
}
bResult = GpResult.ProcessOptions( argc, argv, &bNeedUsageMsg );
if( bResult == FALSE )
{
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_INTERNAL );
if( bNeedUsageMsg == TRUE )
{
ShowMessageEx(stderr, 1, TRUE, GetResString( IDS_TYPE_USAGE ), argv[ 0 ] );
}
EXIT_PROCESS( ERROR_EXIT );
}
// Check if help is specified in the commandline
if( (argc == 2) && ( ( StringCompare ( argv[1], HELP_OPTION, FALSE, 0 ) == 0)
|| (StringCompare ( argv[1], HELP_OPTION1, FALSE, 0 ) == 0) ) )
{
GpResult.DisplayUsage();
EXIT_PROCESS( CLEAN_EXIT );
}
// Call GetLoggingData to get the data for the Logging mode
if( GpResult.GetLoggingData() == FALSE )
{
EXIT_PROCESS( ERROR_EXIT );
}
EXIT_PROCESS( CLEAN_EXIT );
}
/*********************************************************************************************
Routine Description
This function displays the help for GpResult utility
Arguments:
None.
Return Value
None
*********************************************************************************************/
VOID CGpResult::DisplayUsage( void )
{
DWORD dwIndex = 0;
// Displaying main usage
for( dwIndex = ID_HELP_START; dwIndex <= ID_HELP_END; dwIndex++ )
{
ShowMessage( stdout, GetResString( dwIndex ) );
}
}
/*********************************************************************************************
Routine Description
This function processes the command line for the main options
Arguments:
[in] argc : Number of Command line arguments.
[in] argv : Pointer to Command line arguments.
Return Value
TRUE on success
FALSE on failure
*********************************************************************************************/
BOOL CGpResult::ProcessOptions( DWORD argc, LPCWSTR argv[], BOOL *pbNeedUsageMsg )
{
// local variables
PTCMDPARSER2 pcmdOptions = NULL;
__STRING_64 szScope = NULL_STRING;
// temporary local variables
LPWSTR pwszPassword = NULL;
LPWSTR pwszUser = NULL;
LPWSTR pwszServerName = NULL;
PTCMDPARSER2 pOption = NULL;
PTCMDPARSER2 pOptionServer = NULL;
PTCMDPARSER2 pOptionUserName = NULL;
PTCMDPARSER2 pOptionPassword = NULL;
PTCMDPARSER2 pOptionUser = NULL;
PTCMDPARSER2 pOptionVerbose = NULL;
PTCMDPARSER2 pOptionSuperVerbose = NULL;
//
// prepare the command options
pcmdOptions = new TCMDPARSER2[ MAX_CMDLINE_OPTIONS ];
if ( pcmdOptions == NULL )
{
SetLastError((DWORD) E_OUTOFMEMORY );
SaveLastError();
return FALSE;
}
try
{
// get the memory
pwszServerName = m_strServerName.GetBufferSetLength( MAX_STRING_LENGTH );
pwszPassword = m_strPassword.GetBufferSetLength( MAX_STRING_LENGTH );
pwszUser = m_strUser.GetBufferSetLength( MAX_STRING_LENGTH );
// init the password value
StringCopy( pwszPassword, _T( "*" ), MAX_STRING_LENGTH );
}
catch( ... )
{
SetLastError((DWORD) E_OUTOFMEMORY );
SaveLastError();
delete [] pcmdOptions; // clear memory
pcmdOptions = NULL;
return FALSE;
}
// initialize to ZERO's
SecureZeroMemory( pcmdOptions, MAX_CMDLINE_OPTIONS * sizeof( TCMDPARSER2 ) );
// -?
pOption = pcmdOptions + OI_USAGE;
pOption->dwCount = 1;
pOption->dwFlags = CP2_USAGE;
pOption->dwType = CP_TYPE_BOOLEAN;
pOption->pValue = &m_bUsage;
pOption->pwszOptions= OPTION_USAGE;
StringCopyA( pOption->szSignature, "PARSER2", 8 );
// -s
pOption = pcmdOptions + OI_SERVER;
pOption->dwCount = 1;
pOption->pValue = pwszServerName;
pOption->dwType = CP_TYPE_TEXT;
pOption->dwFlags = CP_VALUE_MANDATORY;
StringCopyA( pOption->szSignature, "PARSER2", 8 );
pOption->pwszOptions=OPTION_SERVER;
pOption->dwLength = MAX_STRING_LENGTH;
// -u
pOption = pcmdOptions + OI_USERNAME;
pOption->dwCount = 1;
pOption->dwActuals = 0;
pOption->dwType = CP_TYPE_TEXT;
pOption->dwFlags = CP2_ALLOCMEMORY | CP_VALUE_MANDATORY;
pOption->pValue = NULL;
pOption->pFunction = NULL;
pOption->pFunctionData = NULL;
pOption->pwszOptions=OPTION_USERNAME;
StringCopyA( pOption->szSignature, "PARSER2", 8 );
// -p
pOption = pcmdOptions + OI_PASSWORD;
pOption->dwCount = 1;
pOption->dwType = CP_TYPE_TEXT;
pOption->dwFlags = CP2_VALUE_OPTIONAL;
pOption->pValue = pwszPassword;
pOption->pwszOptions=OPTION_PASSWORD;
pOption->dwLength = MAX_STRING_LENGTH;
StringCopyA( pOption->szSignature, "PARSER2", 8 );
// -v
pOption = pcmdOptions + OI_VERBOSE;
pOption->dwCount = 1;
pOption->dwType = CP_TYPE_BOOLEAN;
pOption->pValue = &m_bVerbose;
pOption->pwszOptions=OPTION_VERBOSE;
StringCopyA( pOption->szSignature, "PARSER2", 8 );
// -z
pOption = pcmdOptions + OI_SUPER_VERBOSE;
pOption->dwCount = 1;
pOption->dwType = CP_TYPE_BOOLEAN;
pOption->pValue = &m_bSuperVerbose;
pOption->pwszOptions=OPTION_SUPER_VERBOSE;
StringCopyA( pOption->szSignature, "PARSER2", 8 );
// -User
pOption = pcmdOptions + OI_USER;
pOption->dwCount = 1;
pOption->dwType = CP_TYPE_TEXT;
pOption->dwFlags = CP_VALUE_MANDATORY;
pOption->pValue = pwszUser;
pOption->dwLength = MAX_STRING_LENGTH;
pOption->pwszOptions=OPTION_USER;
StringCopyA( pOption->szSignature, "PARSER2", 8 );
// -scope
pOption = pcmdOptions + OI_SCOPE;
pOption->dwCount = 1;
pOption->dwActuals = 0;
pOption->dwType = CP_TYPE_TEXT;
pOption->dwFlags = CP_VALUE_MANDATORY | CP2_MODE_VALUES;
pOption->pValue = szScope;
pOption->dwLength = MAX_STRING_LENGTH;
pOption->pwszValues=TEXT_SCOPE_VALUES;
pOption->pwszOptions=OPTION_SCOPE;
StringCopyA( pOption->szSignature, "PARSER2", 8 );
//
// do the parsing
if( DoParseParam2( argc, argv, -1, MAX_CMDLINE_OPTIONS, pcmdOptions, 0 ) == FALSE )
{
delete [] pcmdOptions; // clear memory
pcmdOptions = NULL;
return FALSE; // invalid syntax
}
pOption = pcmdOptions+OI_USERNAME;
m_strUserName =(LPCWSTR) pOption->pValue;
// Do Parse Param succeded so set the flag to indicate that we have to
// show an additional line alongwith the error message
*pbNeedUsageMsg = TRUE;
// release the buffers
m_strServerName.ReleaseBuffer();
m_strPassword.ReleaseBuffer();
m_strUser.ReleaseBuffer();
// check the usage option
if( m_bUsage && ( argc > 2 ) )
{
// No options are accepted with -?
SetReason( ERROR_USAGE );
delete [] pcmdOptions; // clear the cmd parser config info
return FALSE;
}
else if( m_bUsage == TRUE )
{
// should not do the furthur validations
delete [] pcmdOptions; // clear the cmd parser config info
return TRUE;
}
// Check what has been entered for the scope variable
// and set the flag appropriately
if( StringCompare( szScope, TEXT_SCOPE_USER, TRUE, 0 ) == 0 )
{
m_dwScope = SCOPE_USER;
}
else if( StringCompare( szScope, TEXT_SCOPE_COMPUTER, TRUE, 0 ) == 0 )
{
m_dwScope = SCOPE_COMPUTER;
}
//
// now, check the mutually exclusive options
pOptionServer = pcmdOptions + OI_SERVER;
pOptionUserName = pcmdOptions + OI_USERNAME;
pOptionPassword = pcmdOptions + OI_PASSWORD;
pOptionUser = pcmdOptions + OI_USER;
pOptionVerbose = pcmdOptions + OI_VERBOSE;
pOptionSuperVerbose = pcmdOptions + OI_SUPER_VERBOSE;
// "-z" and "-v" are mutually exclusive options
if( pOptionVerbose->dwActuals != 0 && pOptionSuperVerbose->dwActuals != 0 )
{
// invalid syntax
SetReason( ERROR_VERBOSE_SYNTAX );
delete [] pcmdOptions; // clear the cmd parser config info
return FALSE; // indicate failure
}
// "-u" should not be specified without machine names
if( pOptionServer->dwActuals == 0 && pOptionUserName->dwActuals != 0 )
{
// invalid syntax
SetReason( ERROR_USERNAME_BUT_NOMACHINE );
delete [] pcmdOptions; // clear the cmd parser config info
return FALSE; // indicate failure
}
// "-p" should not be specified without "-u"
if( pOptionUserName->dwActuals == 0 && pOptionPassword->dwActuals != 0 )
{
// invalid syntax
SetReason( ERROR_PASSWORD_BUT_NOUSERNAME );
delete [] pcmdOptions; // clear the cmd parser config info
return FALSE;
}
// empty server name is not valid
if( pOptionServer->dwActuals != 0 && m_strServerName.GetLength() == 0 )
{
SetReason( ERROR_SERVERNAME_EMPTY );
delete [] pcmdOptions;
return FALSE;
}
// empty user is not valid
if( pOptionUserName->dwActuals != 0 && m_strUserName.GetLength() == 0 )
{
SetReason( ERROR_USERNAME_EMPTY );
delete [] pcmdOptions;
return FALSE;
}
// empty user is not valid, for the target user
if( pOptionUser->dwActuals != 0 && m_strUser.GetLength() == 0 )
{
SetReason( ERROR_TARGET_EMPTY );
delete [] pcmdOptions;
return FALSE;
}
// if user has specified -s (or) -u and no "-p", then utility should accept password
// the user will be prompted for the password only if establish connection
// fails without the credentials information
m_bNeedPassword = FALSE;
if ( pOptionPassword->dwActuals != 0 && m_strPassword.Compare( L"*" ) == 0 )
{
// user wants the utility to prompt for the password before trying to connect
m_bNeedPassword = TRUE;
}
else if ( pOptionPassword->dwActuals == 0 &&
( pOptionServer->dwActuals != 0 || pOptionUserName->dwActuals != 0 ) )
{
// utility needs to try to connect first and if it fails then prompt for the password
m_bNeedPassword = TRUE;
m_strPassword.Empty();
}
// Check wether we are querying for the local system
if( pOptionServer->dwActuals == 0 )
{
m_bLocalSystem = TRUE;
}
// command-line parsing is successfull
// clear the cmd parser config info
delete [] pcmdOptions;
return TRUE;
}
/*********************************************************************************************
Routine Description:
CGpResult constructor
Arguments:
NONE
Return Value:
NONE
*********************************************************************************************/
CGpResult::CGpResult()
{
// initialize the member variables to defaults
m_pWbemLocator = NULL;
m_pEnumObjects = NULL;
m_pWbemServices = NULL;
m_pAuthIdentity = NULL;
m_pRsopNameSpace = NULL;
m_strServerName = L"";
m_strUserName = L"";
m_strPassword = L"";
m_strUser = L"";
m_strADSIDomain = L"";
m_strADSIServer = L"";
m_pwszPassword = NULL;
m_hOutput = NULL;
m_bVerbose = FALSE;
m_dwScope = SCOPE_ALL;
m_bNeedPassword = FALSE;
m_bLocalSystem = FALSE;
m_bUsage = FALSE;
m_szUserGroups = NULL;
m_hMutex = NULL;
m_NoOfGroups = 0;
m_bPlanning = FALSE;
m_bLogging = FALSE;
m_bUsage = FALSE;
}
/*********************************************************************************************
Routine Description:
CGpResult destructor
Arguments:
NONE
Return Value:
NONE
*********************************************************************************************/
CGpResult::~CGpResult()
{
//
// release WMI / COM interfaces
SAFE_RELEASE( m_pWbemLocator );
SAFE_RELEASE( m_pWbemServices );
SAFE_RELEASE( m_pEnumObjects );
SAFE_RELEASE( m_pRsopNameSpace );
if( m_szUserGroups != NULL )
{
for( DWORD dw=0;dw<=m_NoOfGroups;dw++ )
{
FreeMemory((LPVOID *) &m_szUserGroups[dw] );
}
FreeMemory((LPVOID *)&m_szUserGroups);
}
// free authentication identity structure
// release the existing auth identity structure
WbemFreeAuthIdentity( &m_pAuthIdentity );
// un-initialize the COM library
CoUninitialize();
// Release the object
if( m_hMutex != NULL )
{
CloseHandle( m_hMutex );
}
}
/*********************************************************************************************
Routine Description:
Initializes the GpResult utility
Arguments:
NONE
Return Value:
TRUE : if filters are appropriately specified
FALSE : if filters are errorneously specified
*********************************************************************************************/
BOOL CGpResult::Initialize()
{
// if at all an error occurs, we know that is because of the
// failure in memory allocation, so set the error initially
SetLastError((DWORD) E_OUTOFMEMORY );
SaveLastError();
// initialize the COM library
if ( InitializeCom( &m_pWbemLocator ) == FALSE )
{
return FALSE;
}
//
// Init the console scree buffer structure to zero's
// and then get the console handle and screen buffer information
//
// prepare for status display.
// for this get a handle to the screen output buffer
// but this handle will be null if the output is being redirected. so do not check
// for the validity of the handle. instead try to get the console buffer information
// only in case you have a valid handle to the output screen buffer
SecureZeroMemory( &m_csbi, sizeof( CONSOLE_SCREEN_BUFFER_INFO ) );
if( IsConsoleFile(stdout) )
m_hOutput = GetStdHandle( STD_OUTPUT_HANDLE );
else if( IsConsoleFile(stderr) )
m_hOutput = GetStdHandle( STD_ERROR_HANDLE );
else
m_hOutput = NULL;
if ( m_hOutput != NULL )
{
GetConsoleScreenBufferInfo( m_hOutput, &m_csbi );
}
// initialization is successful
SetLastError( NOERROR ); // clear the error
SetReason( NULL_STRING ); // clear the reason
return TRUE;
}
/*********************************************************************************************
Routine Description:
Initializes the GpResult utility
Arguments:
[in] HANDLE : Handle to the output console
[in] LPCWSTR : String to display
[in] const CONSOLE_SCREEN_BUFFER_INFO& : pointer to the screen buffer
Return Value:
NONE
*********************************************************************************************/
VOID PrintProgressMsg( HANDLE hOutput, LPCWSTR pwszMsg,
const CONSOLE_SCREEN_BUFFER_INFO& csbi )
{
// local variables
COORD coord;
DWORD dwSize = 0;
WCHAR wszSpaces[ 80 ] = L"";
// check the handle. if it is null, it means that output is being redirected. so return
if( hOutput == NULL )
{
return;
}
// set the cursor position
coord.X = 0;
coord.Y = csbi.dwCursorPosition.Y;
// first erase contents on the current line
SecureZeroMemory( wszSpaces, 80 );
SetConsoleCursorPosition( hOutput, coord );
WriteConsoleW( hOutput, Replicate( wszSpaces, L" ", 79, 79 ), 79, &dwSize, NULL );
// now display the message ( if exists )
SetConsoleCursorPosition( hOutput, coord );
if( pwszMsg != NULL )
{
WriteConsoleW( hOutput, pwszMsg, lstrlen( pwszMsg ), &dwSize, NULL );
}
}
BOOL CGpResult::CreateRsopMutex( LPWSTR szMutexName )
{
BOOL bResult = FALSE;
SECURITY_ATTRIBUTES sa;
PSECURITY_DESCRIPTOR psd = NULL;
//
// first try to open the mutex object by its name
// if that fails it means the mutex is not yet created and
// so create it now
//
m_hMutex = OpenMutex( SYNCHRONIZE, FALSE, szMutexName );
if ( m_hMutex == NULL )
{
// check the error code why it failed to open
if ( GetLastError() == ERROR_FILE_NOT_FOUND )
{
// create the security descriptor -- just set the
// Dicretionary Access Control List (DACL)
// in order to provide security, we will deny WRITE_OWNER and WRITE_DAC
// permission to Everyone except to the owner
bResult = ConvertStringSecurityDescriptorToSecurityDescriptor(
L"D:(D;;WOWD;;;WD)(A;;GA;;;WD)", SDDL_REVISION_1, &psd, NULL );
if ( bResult == FALSE )
{
// we encountered error while creating a security descriptor
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
return FALSE;
}
// initialize the SECURITY_ATTRIBUTES structure
SecureZeroMemory( &sa, sizeof( SECURITY_ATTRIBUTES ) );
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = psd;
sa.bInheritHandle = FALSE;
// mutex doesn't exist -- so we need to create it now
m_hMutex = CreateMutex( &sa, FALSE, szMutexName );
if (m_hMutex == NULL )
{
// we are not able to create the mutex
// cannot proceed furthur
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
return FALSE;
}
LocalFree(psd);
}
else
{
// we encounter some error
// cannot proceed furthur
ShowLastErrorEx( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
return FALSE;
}
}
return TRUE;
}